<?xml version="1.0"?>
<rss version="2.0" xmlns:geo="http://www.w3.org/2003/01/geo/wgs84_pos#" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:media="http://search.yahoo.com/mrss/" xmlns:yt="http://gdata.youtube.com/schemas/2007">
   <channel>
      <title>YWebDevs</title>
      <description>Pipes Output</description>
      <link>http://pipes.yahoo.com/pipes/pipe.info?_id=gg6L8PuW3BGXJwFvjtzu1g</link>
      <pubDate>Sun, 29 Nov 2009 07:39:36 -0800</pubDate>
      <generator>http://pipes.yahoo.com/pipes/</generator>
      <item>
         <title>Virtualised Development Environments on a Mac</title>
         <link>http://nefariousdesigns.co.uk/archive/2009/09/virtualised-development-environments-on-a-mac/</link>
         <description>&lt;p&gt;Recently, I bought myself a brand new MacBook Pro, which gave me the perfect opportunity to clean up my development environment. Since I&amp;#8217;ve started doing all of my development on virtual machines, I began thinking about my development workflow: In theory, I should be able to model the perfect server environment virtually.&lt;/p&gt;
&lt;p&gt;I wasn&amp;#8217;t sure what environment I wanted to end up with, but I had a good idea what basic virtual machines I wanted as a starting layout.&lt;/p&gt;
&lt;p&gt;&lt;span id=&quot;more-258&quot;&gt;&lt;/span&gt;&lt;/p&gt;
&lt;h2&gt;The Proposed Environment&lt;/h2&gt;
&lt;p&gt;A basic, well structured development environment should include:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Development Server&lt;/strong&gt; &amp;#8212; Where all development takes place. This will probably have more detailed logs, development dependencies, and a high likelihood of being broken at any given moment in time. Bugs that occur here are likely to be frequent.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Staging Server&lt;/strong&gt; &amp;#8212; A duplicate of the production server that allows testing of build scripts, packages etc. before they are pushed to production. Bugs that occur here are likely to be less frequent and flagged by specific testing.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Production Server&lt;/strong&gt; &amp;#8212; The live environment. By the time the code reaches this server, it should have gone through development testing &lt;em&gt;and&lt;/em&gt; staging testing. This means bugs should be at a bare minimum.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;If bugs arise on either the staging server or the production server, the fixes should be made on the development server and pushed to staging and then production. No code changes should happen on staging or production.&lt;/p&gt;
&lt;p&gt;We could, of course, add more stages between development and live (a quality assurance (QA) server, for instance), and we could even branch the environment to allow for a continuous integration (CI) server (the product of an automated build, and including automated testing; see &lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://en.wikipedia.org/wiki/Continuous_integration&quot;&gt;Wikipedia&amp;#8217;s Continuous Integration page&lt;/a&gt; for more information).&lt;/p&gt;
&lt;p&gt;In my specific case, the environment should be structured thus:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Development Server&lt;/strong&gt; &amp;#8212; The development virtual machine I&amp;#8217;ve been using for the past few months. This VM shares key folders with Mac OS X so that I get the pleasure of using Mac based tools for development (see: TextMate).&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Staging Server&lt;/strong&gt; &amp;#8212; A duplicate of the production server (or as close to as possible) in VM format. This should be the target for my build scripts, and where I run integration tests.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Production Server&lt;/strong&gt; &amp;#8212; My live web server. Only functioning, tested code should ever be pushed here.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;So, rather than developing with just the &lt;em&gt;one&lt;/em&gt; virtual machine, it&amp;#8217;s clear I should be moving forward with &lt;em&gt;two&lt;/em&gt; virtual machines (at least) &amp;#8212; one as the &lt;em&gt;development server&lt;/em&gt;, and one as the &lt;em&gt;staging server&lt;/em&gt;.&lt;/p&gt;
&lt;h2&gt;Linked Clones&lt;/h2&gt;
&lt;p&gt;Once I&amp;#8217;ve built a good master virtual machine as a source &amp;#8212; and set it all up as a basic server, including all the dependencies and packages I want &amp;#8212; I could create duplicates for each server. The drawback to that method is the considerable amount of disk space the independent VMs would take up.&lt;/p&gt;
&lt;p&gt;The second option would be to branch snapshots on the master, setting up one branch as the development server, and another as the staging server. However, this would mean that I would have no way of running the two servers simultaneously, which would be a terrible trudge when attempting to test a build.&lt;/p&gt;
&lt;p&gt;The best solution would be to build &lt;em&gt;linked clones&lt;/em&gt;. A linked clone is a copy of a virtual machine that shares virtual disks with the parent virtual machine in an ongoing manner. This conserves disk space, and allows multiple virtual machines to use the same software installation. It also means we&amp;#8217;ll be able to run the two VMs simultaneously. However, VMWare Fusion (the Mac version of VMWare) doesn&amp;#8217;t actually allow this functionality through the interface; so it has to be done manually.&lt;/p&gt;
&lt;p&gt;When you take a snapshot of a VM, the original virtual disk becomes read-only and a new &lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://en.wikipedia.org/wiki/Copy-on-write&quot;&gt;Copy-On-Write (COW)&lt;/a&gt; disk is created. To create a linked clone manually, we&amp;#8217;re going to set up a virtual machine, then create new ones using that as the base disk. We then snapshot the new VMs so they never try to modify the base disk.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; I pretty much followed the &amp;#8220;&lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://communities.vmware.com/docs/DOC-5611&quot;&gt;HOWTO: Manual Linked Cloning in VMWare Fusion&lt;/a&gt;&amp;#8221; article on the VMWare Communites site. I&amp;#8217;ve recreated the steps below to allow illustration of my particular implementation, and to hopefully save you flicking backwards and forwards between articles.&lt;/p&gt;
&lt;h2&gt;Building the environment&lt;/h2&gt;
&lt;p&gt;The first thing we need to do is create a master VM. This will be our base disk, and the root of all evil… Uh… I mean… The root of all awesome.&lt;/p&gt;
&lt;h3&gt;Create the master VM&lt;/h3&gt;
&lt;p&gt;In my particular instance I&amp;#8217;m creating web servers, so I&amp;#8217;m going to build an Ubuntu VM and base the clones on that. To do this, I&amp;#8217;d recommend following &lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://intranation.com/entries/2009/03/development-virtual-machines-os-x-using-vmware-and/&quot;&gt;Brad Wright&amp;#8217;s excellent Ubuntu VM build tutorial&lt;/a&gt;, right up to the point where you&amp;#8217;ve finished installing VMWare Tools &amp;#8212; we don&amp;#8217;t want to start sharing folders on our base build because we&amp;#8217;ll do that on the development server VM only.&lt;/p&gt;
&lt;p&gt;The next step is to set up all the common packages, dependencies, configurations, and applications on your base VM so that you have the minimum to set up on your clones (and so they&amp;#8217;re as close to one another as possible at the outset; after all, that&amp;#8217;s part of the reason we&amp;#8217;re doing this).&lt;/p&gt;
&lt;p&gt;In my case, I set up the following:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Apache&lt;/li&gt;
&lt;li&gt;PHP&lt;/li&gt;
&lt;li&gt;MySQL&lt;/li&gt;
&lt;li&gt;Python&lt;/li&gt;
&lt;li&gt;Django&lt;/li&gt;
&lt;li&gt;CouchDB&lt;/li&gt;
&lt;li&gt;Twisted&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;I also made sure I&amp;#8217;d configured them all as I wanted them &amp;#8212; including default site layout for Apache &amp;#8212; and included interdependencies like MySQL-Python.&lt;/p&gt;
&lt;p&gt;Once this is complete, we&amp;#8217;ve got a suitable master VM for our linked clones.&lt;/p&gt;
&lt;p&gt;Finally, make sure you back up the &lt;samp&gt;.vmwarevm&lt;/samp&gt; package for your master VM. We&amp;#8217;re going to be editing the package contents, and deleting a bunch of stuff; plus if anything gets hosed in the future, you&amp;#8217;ll be able to restore the master and start over. I&amp;#8217;d recommend creating an archive of the &lt;samp&gt;.vmware&lt;/samp&gt; package and storing it somewhere safe.&lt;/p&gt;
&lt;h3&gt;Prepare the master VM for cloning&lt;/h3&gt;
&lt;p&gt;The only thing we want to keep from the master is the virtual disk, since the rest of the VM is inconsequential to our linked clones. So, once you&amp;#8217;ve definitely made a back-up of the full VM, let&amp;#8217;s change directory to where our VMs are stored, copy out the &lt;samp&gt;.vmdk&lt;/samp&gt; files (virtual machine disk), and delete the master bundle:&lt;/p&gt;
&lt;pre&gt;&lt;samp&gt;$ &lt;kbd&gt;cd /Users/timbo/vms&lt;/kbd&gt;
$ &lt;kbd&gt;ls&lt;/kbd&gt;
master.vmwarevm
$ &lt;kbd&gt;mkdir master&lt;/kbd&gt;
$ &lt;kbd&gt;ls&lt;/kbd&gt;
master master.vmwarevm
$ &lt;kbd&gt;mv master.vmwarevm/*.vmdk master/&lt;/kbd&gt;
$ &lt;kbd&gt;rm -f master.vmwarevm&lt;/kbd&gt;
$ &lt;kbd&gt;ls master&lt;/kbd&gt;
master-s001.vmdk master-s002.vmdk master-s003.vmdk master-s004.vmdk master-s005.vmdk master-s006.vmdk master.vmdk&lt;/samp&gt;&lt;/pre&gt;
&lt;p&gt;Next we need to update the the virtual disk to reflect our changed location and to remove it&amp;#8217;s UUID (Universally Unique Identifier). To do that, we need to edit the root &lt;samp&gt;.vmdk&lt;/samp&gt; file:&lt;/p&gt;
&lt;pre&gt;&lt;samp&gt;$ &lt;kbd&gt;cd master&lt;/kbd&gt;
$ &lt;kbd&gt;mate master.vmdk&lt;/kbd&gt;&lt;/samp&gt;&lt;/pre&gt;
&lt;p&gt;I&amp;#8217;m using TextMate as my editor of choice, but you could easily use vi, vim, nano, BBEdit etc.&lt;/p&gt;
&lt;p&gt;You should see a file that looks something like this:&lt;/p&gt;
&lt;pre&gt;&lt;samp&gt;# Disk DescriptorFile
version=1
encoding=&quot;UTF-8&quot;
CID=96100eeb
parentCID=ffffffff
createType=&quot;twoGbMaxExtentSparse&quot; # Extent description
RW 4192256 SPARSE &quot;master-s001.vmdk&quot;
RW 4192256 SPARSE &quot;master-s002.vmdk&quot;
RW 4192256 SPARSE &quot;master-s003.vmdk&quot;
RW 4192256 SPARSE &quot;master-s004.vmdk&quot;
RW 4192256 SPARSE &quot;master-s005.vmdk&quot;
RW 10240 SPARSE &quot;master-s006.vmdk&quot; # The Disk Data Base
#DDB ddb.uuid = &quot;60 00 C2 99 ab ce aa 92-d3 3e 55 a9 30 e7 c6 dd&quot;
ddb.toolsVersion = &quot;7462&quot;
ddb.adapterType = &quot;lsilogic&quot;
ddb.geometry.sectors = &quot;63&quot;
ddb.geometry.heads = &quot;255&quot;
ddb.geometry.cylinders = &quot;1305&quot;
ddb.virtualHWVersion = &quot;7&quot;&lt;/samp&gt;&lt;/pre&gt;
&lt;p&gt;We need to fix the paths of our &lt;samp&gt;.vmdk&lt;/samp&gt; files so that they will work from other locations. Obviously, for the best results, we should probably use absolute paths so that they work from anywhere. I updated mine like this:&lt;/p&gt;
&lt;pre&gt;&lt;samp&gt;# Extent description
RW 4192256 SPARSE &quot;/Users/timbo/vms/master/master-s001.vmdk&quot;
RW 4192256 SPARSE &quot;/Users/timbo/vms/master/master-s002.vmdk&quot;
RW 4192256 SPARSE &quot;/Users/timbo/vms/master/master-s003.vmdk&quot;
RW 4192256 SPARSE &quot;/Users/timbo/vms/master/master-s004.vmdk&quot;
RW 4192256 SPARSE &quot;/Users/timbo/vms/master/master-s005.vmdk&quot;
RW 10240 SPARSE &quot;/Users/timbo/vms/master/master-s006.vmdk&quot;&lt;/samp&gt;&lt;/pre&gt;
&lt;p&gt;The next thing you should do is remove the UUID line, either by commenting it with a #, or by deleting it entirely:&lt;/p&gt;
&lt;pre&gt;&lt;samp&gt;ddb.uuid = &quot;60 00 C2 99 ab ce aa 92-d3 3e 55 a9 30 e7 c6 dd&quot;&lt;/samp&gt;&lt;/pre&gt;
&lt;p&gt;Once these changes have been made, save the file and exit back to the command line.&lt;/p&gt;
&lt;p&gt;The final thing we should do is write protect these files &amp;#8212; make sure you update your path appropriately:&lt;/p&gt;
&lt;pre&gt;&lt;samp&gt;chmod a-w /Users/timbo/vms/master/*.vmdk&lt;/samp&gt;&lt;/pre&gt;
&lt;p&gt;Our master is now totally prepared for cloning, and can be used repeatedly. In my instance, this means I can now clone it twice; once for the development VM, and once for the staging VM (since it&amp;#8217;s no longer a full VM by itself).&lt;/p&gt;
&lt;h3&gt;Create a clone&lt;/h3&gt;
&lt;p&gt;To create a clone, we need to create the VM in VMWare Fusion. Once you&amp;#8217;re back in the VMWare GUI, do the following:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;Push cmd + N, or select File &amp;gt; New from the menu, to create a new virtual machine.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Click &amp;#8220;Continue without disk&amp;#8221;.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Select &amp;#8220;Create a custom virtual machine&amp;#8221; and click &amp;#8220;Continue&amp;#8221;.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Select the appropriate guest OS type (in my case, Linux/Ubuntu) and click &amp;#8220;Continue&amp;#8221;.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Click &amp;#8220;Customize Settings&amp;#8221;.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Choose a name and location for your clone VM. I chose to call mine &amp;#8220;child&amp;#8221; and saved it in my &lt;samp&gt;~/vms&lt;/samp&gt; directory.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;You should now be looking at the settings of your new VM. Set it up with the same basic settings as you did for the master (256MB RAM, printers disabled), but leave the HDD alone because…&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Edit the HDD settings and delete the disk device by clicking the &amp;#8220;-&amp;#8221; when the device is selected in the list.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Go back to your terminal and delete the &lt;samp&gt;.vmdk&lt;/samp&gt; files in the new VM package:&lt;/p&gt;
&lt;pre&gt;&lt;samp&gt;$ &lt;kbd&gt;cd /Users/timbo/vms/child.vmwarevm&lt;/kbd&gt;
$ &lt;kbd&gt;rm -f *.vmdk&lt;/kbd&gt;&lt;/samp&gt;&lt;/pre&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Now copy the root &lt;samp&gt;.vmdk&lt;/samp&gt; file from your master (the one we edited the paths in earlier) to your clone package:&lt;/p&gt;
&lt;pre&gt;&lt;samp&gt;$ &lt;kbd&gt;cd /Users/timbo/vms&lt;/kbd&gt;
$ &lt;kbd&gt;cp master/master.vmdk child.vmwarevm/&lt;/kbd&gt;&lt;/samp&gt;&lt;/pre&gt;
&lt;p&gt;We need a copy because VMWare will create a &lt;samp&gt;.lck&lt;/samp&gt; file at the same level as this file. With no copy, all the clones would be attempting to use the same &lt;samp&gt;.lck&lt;/samp&gt; file simultaneously, which would prevent them running in parallel.&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Back in the Hard Disk settings pane, press the + button to add a new HDD device.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Select &amp;#8220;Choose existing disk&amp;#8230;&amp;#8221; in the &amp;#8220;File name&amp;#8221; drop-down, and choose the copied metadata file (the one in &lt;samp&gt;child.vmwarevm&lt;/samp&gt;, not the one in the &lt;samp&gt;master&lt;/samp&gt; folder) and uncheck the checkbox &amp;#8212; we&amp;#8217;re happy with the file where it is, we don&amp;#8217;t want to copy or move it since we&amp;#8217;ve already copied it manually (VMWare copies &lt;em&gt;all&lt;/em&gt; the &lt;samp&gt;.vmdk&lt;/samp&gt; files over, and that wouldn&amp;#8217;t save us any disk space at all).&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Finally, create a snapshot of your new VM. This tells Fusion not to try to write to the original disk. I named mine &amp;#8220;Base&amp;#8221; with the comment &amp;#8220;Don&amp;#8217;t delete!&amp;#8221;. Even if you run without the snapshot, because of the read-only permissions on the &lt;samp&gt;.vmdk&lt;/samp&gt; files you shouldn&amp;#8217;t be able to change the original virtual disk, but the clone virtual machine (i.e. not the master) will not be happy.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Run the clone.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Since this is a clone of your master, log in using the same user(s).&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Run the interface configurator:&lt;/p&gt;
&lt;pre&gt;&lt;samp&gt;$ &lt;kbd&gt;ifconfig&lt;/kbd&gt;&lt;/samp&gt;&lt;/pre&gt;
&lt;p&gt;If the &lt;samp&gt;eth0&lt;/samp&gt; interface is showing, skip ahead to step 19, otherwise…&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;To fix this problem, we just need to truncate the udev persistent network rules file:&lt;/p&gt;
&lt;pre&gt;&lt;samp&gt;$ &lt;kbd&gt;cat /dev/null &amp;gt; /etc/udev/rules.d/70-persistent-net.rules&lt;/kbd&gt;&lt;/samp&gt;&lt;/pre&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Reboot the VM to regenerate the rules:&lt;/p&gt;
&lt;pre&gt;&lt;samp&gt;$ &lt;kbd&gt;sudo reboot&lt;/kbd&gt;&lt;/samp&gt;&lt;/pre&gt;
&lt;p&gt;Now wait for your VM to reboot and log back in again.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Run the interface configurator:&lt;/p&gt;
&lt;pre&gt;&lt;samp&gt;$ &lt;kbd&gt;ifconfig&lt;/kbd&gt;&lt;/samp&gt;&lt;/pre&gt;
&lt;p&gt;Make a note of the IP address of the &lt;samp&gt;eth0&lt;/samp&gt; interface, alongside &lt;samp&gt;inet addr:&lt;/samp&gt; since this is the new address for your clone.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Finally, update the hostname of your clone VM by editing and saving the &lt;samp&gt;/etc/hostname&lt;/samp&gt; file:&lt;/p&gt;
&lt;pre&gt;&lt;samp&gt;$ &lt;kbd&gt;sudo vim /etc/hostname&lt;/kbd&gt;&lt;/samp&gt;&lt;/pre&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Restart the hostname service:&lt;/p&gt;
&lt;pre&gt;&lt;samp&gt;$ &lt;kbd&gt;sudo /etc/init.d/hostname.sh start&lt;/kbd&gt;&lt;/samp&gt;&lt;/pre&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Use your clone VM as normal.&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;To create another clone VM for your staging environment, simply repeat the steps above (in the &amp;#8220;Create a clone&amp;#8221; sub-section).&lt;/p&gt;
&lt;h3&gt;Playing nice&lt;/h3&gt;
&lt;p&gt;You might like to run your VMs in &amp;#8220;Headless Mode&amp;#8221; (see &amp;#8220;&lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://communities.vmware.com/docs/DOC-1201&quot;&gt;A Power User&amp;#8217;s Guide to VMWare Fusion&lt;/a&gt;&amp;#8220;), which will prevent you having to open VMWare every time you want to run your VMs. You can activate this option in VMWare itself by running the following command at the terminal of your Mac:&lt;/p&gt;
&lt;pre&gt;&lt;samp&gt;$ &lt;kbd&gt;defaults write com.vmware.fusion fluxCapacitor -bool YES&lt;/kbd&gt;&lt;/samp&gt;&lt;/pre&gt;
&lt;p&gt;Then you&amp;#8217;ll be able to select &amp;#8220;Enter Headless&amp;#8221; under the View menu of your VM in VMWare. Once the VM is running in Headless mode, you can quit VMWare and the VM itself won&amp;#8217;t shut down (until your reboot your Mac).&lt;/p&gt;
&lt;p&gt;If you &lt;em&gt;do&lt;/em&gt; reboot your Mac for any reason, you can boot up the VM using the following command:&lt;/p&gt;
&lt;pre&gt;&lt;samp&gt;$ &lt;kbd&gt;/Library/Application&amp;#92; Support/VMware&amp;#92; Fusion/vmrun start /Users/timbo/vms/child.vmwarevm/child.vmx nogui&lt;/kbd&gt;&lt;/samp&gt;&lt;/pre&gt;
&lt;p&gt;If you&amp;#8217;re going to do lots of VM stuff from the command line, I&amp;#8217;d recommend updating your &lt;samp&gt;$PATH&lt;/samp&gt; variable to include the VMWare Fusion directory by adding the following line to your &lt;samp&gt;.bash_profile&lt;/samp&gt;:&lt;/p&gt;
&lt;pre&gt;&lt;samp&gt;export PATH=&quot;$PATH:/Library/Application Support/VMware Fusion&quot;&lt;/samp&gt;&lt;/pre&gt;
&lt;p&gt;Now you&amp;#8217;ll be able to run &lt;samp&gt;vmrun&lt;/samp&gt; without the directory prefix:&lt;/p&gt;
&lt;pre&gt;&lt;samp&gt;$ &lt;kbd&gt;vmrun start /Users/timbo/vms/child.vmwarevm/child.vmx nogui&lt;/kbd&gt;&lt;/samp&gt;&lt;/pre&gt;
&lt;h3&gt;Shared folders&lt;/h3&gt;
&lt;p&gt;Now that we have a fully functioning development VM, you can continue to set up shared folders between the Ubuntu VM and Mac OS.&lt;/p&gt;
&lt;p&gt;I&amp;#8217;m not going to walk through this again; it&amp;#8217;s covered (including a common read/write issue that can occur) in &lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://intranation.com/entries/2009/03/development-virtual-machines-os-x-using-vmware-and/&quot;&gt;Brad Wright&amp;#8217;s excellent Ubuntu VM build tutorial&lt;/a&gt; which I previously mentioned.&lt;/p&gt;
&lt;p&gt;Once your shared folders are set up and functioning correctly, you can do all your development with your favourite Mac-based tools, but running it on our Ubuntu virtualised development server.&lt;/p&gt;
&lt;p&gt;Incidentally, you can also add new shared folders using &lt;samp&gt;vmrun&lt;/samp&gt;:&lt;/p&gt;
&lt;pre&gt;&lt;samp&gt;$ &lt;kbd&gt;vmrun addSharedFolder /Users/timbo/vms/child.vmwarevm/child.vmx myfolder /Users/timbo/projects/myfolder&lt;/kbd&gt;&lt;/samp&gt;&lt;/pre&gt;
&lt;p&gt;I love &lt;samp&gt;vmrun&lt;/samp&gt;.&lt;/p&gt;
&lt;h2&gt;Summary&lt;/h2&gt;
&lt;p&gt;I now have the environment I set out to achieve; and with the aid of Git, and my own build scripts, I can easily develop, test, and release code in much the same way I would with a live server environment. What&amp;#8217;s more, I have infinitely more control over my environments than I ever had with MAMP, or MacPorts installed instances of Apache, PHP, MySQL etc.&lt;/p&gt;
&lt;p&gt;I guess it&amp;#8217;s safe to say that there&amp;#8217;s really no going back from here.&lt;/p&gt;</description>
         <author>Tim</author>
         <guid isPermaLink="false">http://nefariousdesigns.co.uk/?p=258</guid>
         <pubDate>Sun, 06 Sep 2009 06:23:37 -0700</pubDate>
      </item>
      <item>
         <title>CouchDB&amp;#8217;s RESTful API</title>
         <link>http://nefariousdesigns.co.uk/archive/2009/08/couchdbs-restful-api/</link>
         <description>&lt;p&gt;I&amp;#8217;ve recently been playing with Apache CouchDB; a distributed, fault-tolerant and schema-free document-oriented database. CouchDB supplies a RESTful API for the manipulation of data within it. This is a great demonstration of REST at work, so I thought I&amp;#8217;d illustrate its usage in a quick post.&lt;/p&gt;
&lt;p&gt;Let&amp;#8217;s get the technical details out of the way first: CouchDB makes use of HTTP verbs &amp;#8212; GET, PUT, POST, and DELETE &amp;#8212; and handles requests and responses in JSON only. This means it is entirely possible to utilise CouchDB using JavaScript alone. For the purpose of these examples, however, I&amp;#8217;ll be using cURL, which is easier to follow along with via the command line.&lt;/p&gt;
&lt;p&gt;&lt;span id=&quot;more-241&quot;&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;My CouchDB server is running on my dev Ubuntu VM, on the default port of 5984. I&amp;#8217;ve also set up a &amp;#8220;couchhost&amp;#8221; alias to the VM in my hosts file, to make my requests more readable.&lt;/p&gt;
&lt;h2&gt;Creating databases&lt;/h2&gt;
&lt;p&gt;The first thing we should do is create a database within our CouchDB server. To do that, we use the PUT verb:&lt;/p&gt;
&lt;pre&gt;&lt;samp&gt;$ &lt;kbd&gt;curl -X PUT http://couchhost:5984/fu&lt;/kbd&gt;
{&quot;ok&quot;:true}&lt;/samp&gt;&lt;/pre&gt;
&lt;p&gt;In the command above, we specified the database name in the resource URI &amp;#8212; which is the correct usage of PUT &amp;#8212; and received a JSON object response. As you can see, that JSON object contains a single field; the boolean &amp;#8220;ok&amp;#8221;, with a value of true.&lt;/p&gt;
&lt;p&gt;We can obtain a list of all the databases on our CouchDB server, by sending it a GET request to the _all_dbs resource:&lt;/p&gt;
&lt;pre&gt;&lt;samp&gt;$ &lt;kbd&gt;curl -X GET http://couchhost:5984/_all_dbs&lt;/kbd&gt;
[&quot;fu&quot;]&lt;/samp&gt;&lt;/pre&gt;
&lt;p&gt;Here we receive an array response containing all our database ids. In this case, we only have our &amp;#8220;fu&amp;#8221; database.&lt;/p&gt;
&lt;p&gt;Let&amp;#8217;s try adding another:&lt;/p&gt;
&lt;pre&gt;&lt;samp&gt;$ &lt;kbd&gt;curl -X PUT http://couchhost:5984/bar&lt;/kbd&gt;
{&quot;ok&quot;:true}&lt;/samp&gt;&lt;/pre&gt;
&lt;p&gt;Since we&amp;#8217;ve received an ok response, let&amp;#8217;s list all the databases again:&lt;/p&gt;
&lt;pre&gt;&lt;samp&gt;$ &lt;kbd&gt;curl -X GET http://couchhost:5984/_all_dbs&lt;/kbd&gt;
[&quot;fu&quot;,&quot;bar&quot;]&lt;/samp&gt;&lt;/pre&gt;
&lt;p&gt;Now we can see multiple values in the array response.&lt;/p&gt;
&lt;p&gt;We can obtain information about a specific database by sending a GET request to its URI:&lt;/p&gt;
&lt;pre&gt;&lt;samp&gt;$ &lt;kbd&gt;curl -X GET http://couchhost:5984/fu&lt;/kbd&gt;
{&quot;db_name&quot;:&quot;fu&quot;,&quot;doc_count&quot;:0,&quot;doc_del_count&quot;:0,&quot;update_seq&quot;:0,&quot;compact_running&quot;:false,&quot;disk_size&quot;:4096}&lt;/samp&gt;&lt;/pre&gt;
&lt;p&gt;Here we can see, amongst other things, the number of documents in the database &amp;#8212; none &amp;#8212; and how much diskspace the database is taking up &amp;#8212; 4k.&lt;/p&gt;
&lt;h2&gt;CouchDB documents&lt;/h2&gt;
&lt;p&gt;A CouchDB document is simply a JSON object with some associated metadata. This is an example document (lifted from the CouchDB documentation):&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{ &quot;_id&quot;:&quot;discussion_tables&quot;, &quot;_rev&quot;:&quot;D1C946B7&quot;, &quot;Sunrise&quot;:true, &quot;Sunset&quot;:false, &quot;FullHours&quot;:[1,2,3,4,5,6,7,8,9,10], &quot;Activities&quot;:[ { &quot;Name&quot;:&quot;Football&quot;, &quot;Duration&quot;:2, &quot;DurationUnit&quot;:&quot;Hours&quot; }, { &quot;Name&quot;:&quot;Breakfast&quot;, &quot;Duration&quot;:40, &quot;DurationUnit&quot;:&quot;Minutes&quot;, &quot;Attendees&quot;:[ &quot;Jan&quot;, &quot;Damien&quot;, &quot;Laura&quot;, &quot;Gwendolyn&quot;, &quot;Roseanna&quot; ] } ]
}&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;As you can see, a CouchDB document can handle multiple types of data, including arrays and nested objects. By default the structure is flat; in this particular case, the &amp;#8220;Activities&amp;#8221; attribute is structure imposed by the user.&lt;/p&gt;
&lt;p&gt;It&amp;#8217;s also worth noting that any top-level fields with a name that starts with an underscore prefix are reserved.&lt;/p&gt;
&lt;h3&gt;Adding documents&lt;/h3&gt;
&lt;p&gt;So let&amp;#8217;s define a document for one of our databases:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{ &quot;FirstName&quot;:&quot;Isabella&quot;, &quot;FamilyName&quot;:&quot;Huegdon&quot;, &quot;Age&quot;:2, &quot;Likes&quot;:[ &quot;noise&quot;, &quot;animals&quot;, &quot;chocolate&quot;, &quot;kicking Milly&quot;, &quot;throwing tantrums&quot; ]
}&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This is a fairly straight forward document that includes several different types of data. To add it to our database, let&amp;#8217;s use an HTTP POST request:&lt;/p&gt;
&lt;pre&gt;&lt;samp&gt;$ &lt;kbd&gt;curl -X POST http://couchhost:5984/fu &amp;#92;
-H 'Content-Type: application/json' &amp;#92;
-d '{&quot;FirstName&quot;:&quot;Isabella&quot;,&quot;FamilyName&quot;:&quot;Huegdon&quot;,&quot;Age&quot;:2,&quot;Likes&quot;:[&quot;noise&quot;,&quot;animals&quot;,&quot;chocolate&quot;,&quot;kicking Milly&quot;,&quot;throwing tantrums&quot;]}'&lt;/kbd&gt;
{&quot;ok&quot;:true,&quot;id&quot;:&quot;30d53965f5aec18391c258faa66921c1&quot;,&quot;rev&quot;:&quot;2348720638&quot;}&lt;/samp&gt;&lt;/pre&gt;
&lt;p&gt;Because we&amp;#8217;ve used POST, CouchDB has automagically assigned our document an identifier. You can see this in the id attribute of the response object. But what if we want to specify our own id? Simple; we use HTTP PUT instead.&lt;/p&gt;
&lt;p&gt;Let&amp;#8217;s define another document:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{ &quot;FirstName&quot;:&quot;Amélie&quot;, &quot;FamilyName&quot;:&quot;Huegdon&quot;, &quot;Age&quot;:2, &quot;Likes&quot;:[ &quot;noise&quot;, &quot;animals&quot;, &quot;chocolate&quot;, &quot;hitting Izzy&quot;, &quot;running and screaming&quot; ]
}&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;And now let&amp;#8217;s add that document using HTTP PUT:&lt;/p&gt;
&lt;pre&gt;&lt;samp&gt;$ &lt;kbd&gt;curl -X PUT http://couchhost:5984/fu/milly-huegdon &amp;#92;
-H 'Content-Type: application/json' &amp;#92;
-d '{&quot;FirstName&quot;:&quot;Amélie&quot;,&quot;FamilyName&quot;:&quot;Huegdon&quot;,&quot;Age&quot;:2,&quot;Likes&quot;:[&quot;noise&quot;,&quot;animals&quot;,&quot;chocolate&quot;,&quot;hitting Izzy&quot;,&quot;running and screaming&quot;]}'&lt;/kbd&gt;
{&quot;ok&quot;:true,&quot;id&quot;:&quot;milly-huegdon&quot;,&quot;rev&quot;:&quot;3414255320&quot;}&lt;/samp&gt;&lt;/pre&gt;
&lt;p&gt;This time, we can see our specified id in the id attribute of the response object.&lt;/p&gt;
&lt;p&gt;Now let&amp;#8217;s have a look what documents we&amp;#8217;ve got in the database, using the _all_docs resource, beneath our database:&lt;/p&gt;
&lt;pre&gt;&lt;samp&gt;$ &lt;kbd&gt;curl -X GET http://couchhost:5984/fu/_all_docs&lt;/kbd&gt;
{ &quot;total_rows&quot;:2, &quot;offset&quot;:0, &quot;rows&quot;:[ { &quot;id&quot;:&quot;30d53965f5aec18391c258faa66921c1&quot;, &quot;key&quot;:&quot;30d53965f5aec18391c258faa66921c1&quot;, &quot;value&quot;:{&quot;rev&quot;:&quot;2348720638&quot;} }, { &quot;id&quot;:&quot;milly-huegdon&quot;, &quot;key&quot;:&quot;milly-huegdon&quot;, &quot;value&quot;:{&quot;rev&quot;:&quot;3414255320&quot;} } ]
}&lt;/samp&gt;&lt;/pre&gt;
&lt;p&gt;Note: I&amp;#8217;ve styled the response here for ease of reading; your cURL output will lack indenting but will contain the same information.&lt;/p&gt;
&lt;p&gt;Here we can see, from the total_rows attribute, that there are 2 documents in our database; and we can see the metadata for those documents in the rows attribute array.&lt;/p&gt;
&lt;p&gt;To obtain the actual document, we just need to send an HTTP GET request to the document&amp;#8217;s URI:&lt;/p&gt;
&lt;pre&gt;&lt;samp&gt;$ &lt;kbd&gt;curl -X GET http://couchhost:5984/fu/milly-huegdon&lt;/kbd&gt;
{ &quot;_id&quot;:&quot;milly-huegdon&quot;, &quot;_rev&quot;:&quot;3414255320&quot;, &quot;FirstName&quot;:&quot;Am&amp;#92;u00e9lie&quot;, &quot;FamilyName&quot;:&quot;Huegdon&quot;, &quot;Age&quot;:2, &quot;Likes&quot;:[ &quot;noise&quot;, &quot;animals&quot;, &quot;chocolate&quot;, &quot;hitting Izzy&quot;, &quot;running and screaming&quot; ]
}&lt;/samp&gt;&lt;/pre&gt;
&lt;p&gt;Once again, I&amp;#8217;ve styled the response somewhat for readability. In this instance, you can also see that CouchDB can handle unicode characters (since JSON should always be encoded as UTF-8) from the FirstName attribute.&lt;/p&gt;
&lt;h2&gt;Deleting items&lt;/h2&gt;
&lt;p&gt;Deletion of documents and databases from our CouchDB server couldn&amp;#8217;t be simpler. All we need to do is send an HTTP DELETE request.&lt;/p&gt;
&lt;p&gt;To remove the bar database we created earlier, we send the following request:&lt;/p&gt;
&lt;pre&gt;&lt;samp&gt;$ &lt;kbd&gt;curl -X DELETE http://couchhost:5984/bar&lt;/kbd&gt;
{&quot;ok&quot;:true}&lt;/samp&gt;&lt;/pre&gt;
&lt;h2&gt;Summary&lt;/h2&gt;
&lt;p&gt;You are now able to create and delete items from your CouchDB database. This is all you&amp;#8217;re going to need if you just want to use CouchDB as a persistent document store; however, if you want to query the data in your databases, you&amp;#8217;re going to need to make use of CouchDB Views. I&amp;#8217;ll cover those in a later blog post.&lt;/p&gt;
&lt;p&gt;I&amp;#8217;m going to continue to play with CouchDB over the next week or so and will continue to blog about it (with the hope of using the blog posts as the basis for a TechTalk at Yahoo! Europe &amp;#8212; slides possibly to follow on SlideShare). For now, you should be able to see that CouchDB is a wonderfully easy thing to use, thanks to its entirely RESTful API and its use of JSON as a request and response format.&lt;/p&gt;</description>
         <author>Tim</author>
         <guid isPermaLink="false">http://nefariousdesigns.co.uk/?p=241</guid>
         <pubDate>Sat, 01 Aug 2009 03:06:43 -0700</pubDate>
      </item>
      <item>
         <title>CouchDB on an Ubuntu development VM</title>
         <link>http://nefariousdesigns.co.uk/archive/2009/07/couchdb-on-an-ubuntu-development-vm/</link>
         <description>&lt;p&gt;I&amp;#8217;ve recently set-up &lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://couchdb.apache.org/&quot;&gt;CouchDB&lt;/a&gt; on the &lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://nefariousdesigns.co.uk/archive/2009/04/a-better-os-x-development-environment/&quot;&gt;Ubuntu 8.10 (Intrepid Ibex) virtual machine I use for development&lt;/a&gt;. This was a relatively pain-free experience and I thought I&amp;#8217;d outline what I did here for the benefit of others (and my future self).&lt;/p&gt;
&lt;p&gt;&lt;span id=&quot;more-231&quot;&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;Firstly, I decided to install using the aptitude package, rather than from source. If you&amp;#8217;re interested in building the most recent version, I&amp;#8217;d recommend taking a look at &lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://isolani.co.uk/blog/web/InstallingCouchdbOnJeos804&quot;&gt;Isofarro&amp;#8217;s handy &amp;#8220;Installing CouchDB on JeOS 8.04&amp;#8243; post&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;To begin, install the package:&lt;/p&gt;
&lt;pre&gt;&lt;samp&gt;$ &lt;kbd&gt;sudo apt-get install couchdb&lt;/kbd&gt;&lt;/samp&gt;&lt;/pre&gt;
&lt;p&gt;Once the package has downloaded and installed, you should check the status to see if it&amp;#8217;s running correctly:&lt;/p&gt;
&lt;pre&gt;&lt;samp&gt;$ &lt;kbd&gt;sudo /etc/init.d/couchdb status&lt;/kbd&gt;&lt;/samp&gt;&lt;/pre&gt;
&lt;p&gt;If you see the following output, then CouchDB is running successfully:&lt;/p&gt;
&lt;pre&gt;&lt;samp&gt;Apache CouchDB is running as process 32651. Time to relax.&lt;/samp&gt;&lt;/pre&gt;
&lt;p&gt;If you don&amp;#8217;t see that output, try starting CouchDB manually. I needed to do this:&lt;/p&gt;
&lt;pre&gt;&lt;samp&gt;$ &lt;kbd&gt;sudo /etc/init.d/couchdb start&lt;/kbd&gt;&lt;/samp&gt;&lt;/pre&gt;
&lt;p&gt;And then check the status again:&lt;/p&gt;
&lt;pre&gt;&lt;samp&gt;$ &lt;kbd&gt;sudo /etc/init.d/couchdb status&lt;/kbd&gt;
Apache CouchDB is running as process 32651. Time to relax.&lt;/samp&gt;&lt;/pre&gt;
&lt;p&gt;If you&amp;#8217;re still not getting the correct status, you&amp;#8217;ll need to refer to the &lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://couchdb.apache.org/docs/&quot;&gt;CouchDB documentation&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Next, you should check that you can access CouchDB over HTTP on the default port of 5984. To do that, I used curl:&lt;/p&gt;
&lt;pre&gt;&lt;samp&gt;$ &lt;kbd&gt;curl http://localhost:5984/&lt;/kbd&gt;&lt;/samp&gt;&lt;/pre&gt;
&lt;p&gt;Which should return the following response:&lt;/p&gt;
&lt;pre&gt;&lt;samp&gt;{&quot;couchdb&quot;:&quot;Welcome&quot;,&quot;version&quot;:&quot;0.8.0-incubating&quot;}&lt;/samp&gt;&lt;/pre&gt;
&lt;p&gt;The final step, to make sure you can access CouchDB externally to your dev VM, is to make sure the CouchDB configuration isn&amp;#8217;t bound to the loopback address (127.0.0.1) &amp;#8212; which it is by default. To do that, you&amp;#8217;ll need to edit the couch.ini file:&lt;/p&gt;
&lt;pre&gt;&lt;samp&gt;$ &lt;kbd&gt;sudo vim /etc/couchdb/couch.ini&lt;/kbd&gt;&lt;/samp&gt;&lt;/pre&gt;
&lt;p&gt;And comment out the following line:&lt;/p&gt;
&lt;pre&gt;&lt;samp&gt;BindAddress=127.0.0.1&lt;/samp&gt;&lt;/pre&gt;
&lt;p&gt;You can also change the port that CouchDB is running on in this configuration file if you so desire.&lt;/p&gt;
&lt;p&gt;Finally, you&amp;#8217;ll need to restart CouchDB:&lt;/p&gt;
&lt;pre&gt;&lt;samp&gt;$ &lt;kbd&gt;sudo /etc/init.d/couchdb stop&lt;/kbd&gt;
$ &lt;kbd&gt;sudo /etc/init.d/couchdb start&lt;/kbd&gt;&lt;/samp&gt;&lt;/pre&gt;
&lt;p&gt;Now you should be able to log into Futon, the browser-based CouchDB admin system, on the following address:&lt;/p&gt;
&lt;pre&gt;&lt;samp&gt;http://mydevbox:5984/_utils/&lt;/samp&gt;&lt;/pre&gt;
&lt;p&gt;Huzzah!&lt;/p&gt;</description>
         <author>Tim</author>
         <guid isPermaLink="false">http://nefariousdesigns.co.uk/?p=231</guid>
         <pubDate>Wed, 29 Jul 2009 09:41:41 -0700</pubDate>
      </item>
      <item>
         <title>Unit Testing: The Basics</title>
         <link>http://nefariousdesigns.co.uk/archive/2009/05/unit-testing-the-basics/</link>
         <description>&lt;p&gt;As a web development manager, it&amp;#8217;s part of my job to be involved in defining best practices for my team. This means defining a set of standard practices that will benefit the whole team throughout the entire development process. A good example of one such best practice would be code testing.&lt;/p&gt;
&lt;p&gt;Testing, for web developers, is usually a fairly disorganised affair. Most of the time, we test &amp;#8220;on the job&amp;#8221;, i.e., we code something and then we run it; if it breaks, we fix it. In fact, often, the thought of actually structuring our testing process can seem somewhat of an over complication. This is certainly not the case.&lt;/p&gt;
&lt;p&gt;The benefits of a structured testing process are legion, as any software engineer will attest. At the very least, it provides confidence in our code &amp;#8212; something which can only be of incredible benefit when code is shared across a wider team. At its best, the tests we write can influence the way we develop the code being tested; and save effort, time, and money.&lt;/p&gt;
&lt;p&gt;In this post I&amp;#8217;m going to look at &amp;#8220;unit testing&amp;#8221;, and how it can be of benefit to web developers in general.&lt;/p&gt;
&lt;p&gt;&lt;span id=&quot;more-187&quot;&gt;&lt;/span&gt;&lt;/p&gt;
&lt;h2&gt;What &lt;em&gt;is&lt;/em&gt; unit testing?&lt;/h2&gt;
&lt;p&gt;Unit testing is the process of validating and verifying the individual &amp;#8220;units&amp;#8221; of code in a system. A unit is the smallest testable part of a system or application. In the majority of cases within web development, these units are usually individual functions or methods of our object-oriented back-end and front-end code.&lt;/p&gt;
&lt;p&gt;At this point, it&amp;#8217;s probably worth noting that unit testing is really only applicable to functional code, such as PHP, JavaScript, Python, Perl, Ruby etc., because it breaks down into units nicely. Testing mark-up and CSS is a slightly different process and one that I may look at in a future blog post.&lt;/p&gt;
&lt;h2&gt;A note on language&lt;/h2&gt;
&lt;p&gt;The concept of unit testing is entirely language agnostic, therefore the examples in the following tutorials can be ported to PHP, Perl, Ruby, JavaScript, or any other functional or object-oriented language you are using.&lt;/p&gt;
&lt;p&gt;I&amp;#8217;ll use Python as the language for all examples in this post as it&amp;#8217;s my current weapon of choice (and the interactive interpreter is very handy for trying out ideas); if you&amp;#8217;ve never seen Python syntax, don&amp;#8217;t worry, it&amp;#8217;s easily understandable (if you want more information, take a look at &lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://docs.python.org/tutorial/&quot;&gt;the Python tutorial&lt;/a&gt;).&lt;/p&gt;
&lt;h2&gt;Writing a simple test&lt;/h2&gt;
&lt;p&gt;To begin with, let&amp;#8217;s imagine we have a function for calculating the area of a rectangle:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;def get_area_of_rect( width, height ): return width * height&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Let&amp;#8217;s paste this function into the interactive interpreter, so that we can play with it:&lt;/p&gt;
&lt;pre&gt;&lt;samp&gt;&amp;gt;&amp;gt;&amp;gt; &lt;kbd&gt;def get_area_of_rect( width, height ):&lt;/kbd&gt;
... &lt;kbd&gt; return width * height&lt;/kbd&gt;
...
&amp;gt;&amp;gt;&amp;gt; &lt;/samp&gt;&lt;/pre&gt;
&lt;p&gt;Now if we call it, we&amp;#8217;ll receive the area of our rectangle like so:&lt;/p&gt;
&lt;pre&gt;&lt;samp&gt;&amp;gt;&amp;gt;&amp;gt; &lt;kbd&gt;get_area_of_rect( 2, 3 )&lt;/kbd&gt;
6
&amp;gt;&amp;gt;&amp;gt;&lt;/samp&gt;&lt;/pre&gt;
&lt;p&gt;Now if we wanted to test this function, we could call it with a some defined parameters and test the output against our expectations:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;def test_get_area_of_rect(): width = 2 height = 3 expected_result = 6 result = get_area_of_rect( width, height ) if result == expected_result: print &quot;Test passed: Received expected result!&quot;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Now if we run our test, we should see the following:&lt;/p&gt;
&lt;pre&gt;&lt;samp&gt;&amp;gt;&amp;gt;&amp;gt; &lt;kbd&gt;test_get_area_of_rect()&lt;/kbd&gt;
Test passed: Received expected result!
&amp;gt;&amp;gt;&amp;gt;&lt;/samp&gt;&lt;/pre&gt;
&lt;p&gt;Brilliant; our code passed the test because the &lt;em&gt;expected&lt;/em&gt; result was the same as the &lt;em&gt;actual&lt;/em&gt; result &amp;#8212; however, that&amp;#8217;s actually not very useful to us. It&amp;#8217;s far more important that our tests can trap &lt;em&gt;failing&lt;/em&gt; code than code that works.&lt;/p&gt;
&lt;p&gt;Imagine our &lt;code&gt;get_area_of_rect&lt;/code&gt; function had been updated as follows:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;def get_area_of_rect( width, height ): return width / height&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Anyone with rudimentary maths skills can tell that this will no longer return the correct area of a rectangle. In fact, if we rerun our test, we&amp;#8217;ll get no output:&lt;/p&gt;
&lt;pre&gt;&lt;samp&gt;&amp;gt;&amp;gt;&amp;gt; &lt;kbd&gt;test_get_area_of_rect()&lt;/kbd&gt;
&amp;gt;&amp;gt;&amp;gt;&lt;/samp&gt;&lt;/pre&gt;
&lt;p&gt;A fat lot of good &lt;em&gt;that&lt;/em&gt; is. If our code is failing for some reason, we want to know about it. After all, that&amp;#8217;s the whole reason for testing it.&lt;/p&gt;
&lt;p&gt;Let&amp;#8217;s update the &lt;code&gt;if&lt;/code&gt; statement in our &lt;code&gt;test_get_area_of_rect&lt;/code&gt; function:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;if not result == expected_result: raise AssertionError
else: print &quot;Test passed: Received expected result!&quot;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;In fact, we could probably dump the &lt;code&gt;else&lt;/code&gt; clause since it&amp;#8217;s of little real importance except for logging purposes:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;if not result == expected_result: raise AssertionError&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;That&amp;#8217;s nicer, but Python provides us a shortcut to this &lt;code&gt;if not &amp;hellip; raise AssertionError&lt;/code&gt; syntax with the &lt;code&gt;assert&lt;/code&gt; statement:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;assert result == expected_result&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;With that in mind, the &lt;code&gt;test_get_area_of_rect&lt;/code&gt; function should now look like this:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;def test_get_area_of_rect(): width = 2 height = 3 expected_result = 6 result = get_area_of_rect( width, height ) assert result == expected_result&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;If we run our test again, we should receive more constructive output, considering our &lt;code&gt;get_area_of_rect&lt;/code&gt; function is still dividing:&lt;/p&gt;
&lt;pre&gt;&lt;samp&gt;&amp;gt;&amp;gt;&amp;gt; &lt;kbd&gt;test_get_area_of_rect()&lt;/kbd&gt;
Traceback (most recent call last): File &quot; &quot;, line 1, in  File &quot; &quot;, line 8, in test_get_area_of_rect
AssertionError
&amp;gt;&amp;gt;&amp;gt;&lt;/samp&gt;&lt;/pre&gt;
&lt;p&gt;We now have a decent automated test, but we&amp;#8217;re only checking a single expected result. If, for instance, we passed in a width of 1 and a height of 1, both multiplication and division would return the same result: 1. This means that we should pass multiple sets of width and height parameters and test against their expected results. Since these parameters will be constant, let&amp;#8217;s define them as tuples and loop through them, testing each in turn:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;def test_get_area_of_rect(): known_values = ( ( 0, 0, 0 ), ( 1, 1, 1 ), ( 2, 2, 4 ), ( 2, 3, 6 ), ( 3, 0, 0 ) ) for width, height, expected_result in known_values: result = get_area_of_rect( width, height ) assert result == expected_result&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;As you can see, we&amp;#8217;re now passing several sets of parameters. Each set of parameters is valid, and as such, we should expect a successful outcome from our &lt;code&gt;get_area_of_rect()&lt;/code&gt; call.&lt;/p&gt;
&lt;p&gt;Now if we run our test, we should get something like the following:&lt;/p&gt;
&lt;pre&gt;&lt;samp&gt;&amp;gt;&amp;gt;&amp;gt; &lt;kbd&gt;test_get_area_of_rect()&lt;/kbd&gt;
Traceback (most recent call last): File &quot; &quot;, line 1, in  File &quot; &quot;, line 8, in test_get_area_of_rect File &quot; &quot;, line 2, in get_area_of_rect
ZeroDivisionError: integer division or modulo by zero
&amp;gt;&amp;gt;&amp;gt;&lt;/samp&gt;&lt;/pre&gt;
&lt;p&gt;Ah ha! By passing multiple sets of parameters we&amp;#8217;ve uncovered more significant information regarding the &lt;code&gt;AssertionError&lt;/code&gt; that was raised earlier; we have a division by zero error on line 2 of &lt;code&gt;get_area_of_rect&lt;/code&gt;. This has supplied us with all the information we need to fix our error, so let&amp;#8217;s take a look at that function again:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;def get_area_of_rect( width, height ): # Line 1 return width / height # Line 2&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Change the division back to multiplication, like so:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;def get_area_of_rect( width, height ): # Line 1 return width * height # Line 2&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;And then rerun our test:&lt;/p&gt;
&lt;pre&gt;&lt;samp&gt;&amp;gt;&amp;gt;&amp;gt; &lt;kbd&gt;test_get_area_of_rect()&lt;/kbd&gt;
&amp;gt;&amp;gt;&amp;gt; &lt;/samp&gt;&lt;/pre&gt;
&lt;p&gt;We get no output at all because the test passed successfully. As the old proverb goes, &amp;#8220;no news is good news&amp;#8221;.&lt;/p&gt;
&lt;p&gt;Now if we add to our original code in the future, we&amp;#8217;ll still be able to run this testing code to see what has been affected. What&amp;#8217;s more, we can add to it by writing &lt;em&gt;more&lt;/em&gt; tests, should the complexity grow. In fact, creating an extensive suite of tests is generally the aim of unit testing, but to do so, it&amp;#8217;s a good idea to utilise a testing framework, which I&amp;#8217;ll look at in the next post of this series.&lt;/p&gt;
&lt;h2&gt;Summary&lt;/h2&gt;
&lt;p&gt;Writing tests for code enables more efficient debugging, faster bug fixing, and an overall confidence in the quality of your code. Furthermore, the rest of your team (or whomsoever you&amp;#8217;re sharing said code with) will equally have confidence thanks to the tests included.&lt;/p&gt;
&lt;p&gt;In brief, here&amp;#8217;s what we&amp;#8217;ve learnt about unit testing:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;It&amp;#8217;s most important that your tests catch failure, not success.&lt;/li&gt;
&lt;li&gt;Test the smallest amount of code, or &amp;#8220;unit&amp;#8221;, possible each time.&lt;/li&gt;
&lt;li&gt;Test as many different parameters, inputs, and outputs as possible.&lt;/li&gt;
&lt;li&gt;Run the tests often.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;The next post&lt;/h2&gt;
&lt;p&gt;In the next post, I&amp;#8217;ll be expanding on unit testing by looking at test frameworks, test architecture, code coverage, and other more advanced techniques that can improve your testing environment.&lt;/p&gt;</description>
         <author>Tim</author>
         <guid isPermaLink="false">http://nefariousdesigns.co.uk/?p=187</guid>
         <pubDate>Sun, 03 May 2009 04:36:52 -0700</pubDate>
      </item>
      <item>
         <title>Housekeeping</title>
         <link>http://nefariousdesigns.co.uk/archive/2009/04/housekeeping/</link>
         <description>&lt;p&gt;I&amp;#8217;ve just completed some quick housekeeping on the site &amp;#8212; mostly on my feed.&lt;/p&gt;
&lt;p&gt;I noticed last night that &lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://www.feedburner.com/google&quot;&gt;Google had acquired Feedburner&lt;/a&gt;, and that I needed to port my feed over to my Google account. At the same time, I swapped the feed to use Atom instead of RSS. Having completed that, I decided to address a problem with my feed that&amp;#8217;s been bugging me for some time:&lt;/p&gt;
&lt;p&gt;My feed has always published only an excerpt of each post, instead of the full post. This is because I use the &amp;#8220;more&amp;#8221; break functionality in Wordpress for the introduction snippets in the bespoke home page theme files, instead of writing an entirely separate excerpt. On previous versions of Wordpress, this also limited the RSS feed regardless of whether you had specifically chosen the &amp;#8220;display full article&amp;#8221; option in the syndication settings. I&amp;#8217;ve had a couple of complaints about this, since most developers seem to prefer reading articles in their feed readers &amp;#8212; and so do I, for that matter.&lt;/p&gt;
&lt;p&gt;Last time I needed to fix this problem, I had a hell of a time trying to find the offending code in the horrific Wordpress PHP. Thankfully, since then, the bug has been fixed so all I needed to do was update Wordpress. Having completed that update, my feed should now be working as intended originally.&lt;/p&gt;
&lt;p&gt;The next step, it seems, will be getting off Wordpress to something home-grown.&lt;/p&gt;</description>
         <author>Tim</author>
         <guid isPermaLink="false">http://nefariousdesigns.co.uk/?p=183</guid>
         <pubDate>Mon, 13 Apr 2009 03:14:55 -0700</pubDate>
      </item>
      <item>
         <title>A better OS X development environment</title>
         <link>http://nefariousdesigns.co.uk/archive/2009/04/a-better-os-x-development-environment/</link>
         <description>&lt;p&gt;When I first began developing using a Mac I made use of the bundled versions of Apache and PHP that were included in OS X Tiger. This meant I only needed to install MySQL to be able to develop fairly complex websites.&lt;/p&gt;
&lt;p&gt;However, as my requirements evolved, I discovered that recompiling PHP to include support for features such as HTML Tidy was going to be a pain in the proverbials. So, following advice from friends, I opted to install another version of Apache, PHP5, and MySQL using MacPorts package management. This required minimal configuration and allowed me to easily activate or deactivate features on install &amp;#8212; and it also allowed me to add to my environment as I learnt new skills; including Python and Django.&lt;/p&gt;
&lt;p&gt;Recently, however, this became an issue again, as I attempted to install mod_wsgi in the MacPorts Apache. No matter how hard I tried, I just couldn&amp;#8217;t get it working with more complex Python scripts. At this point, I sought more help from my friends and, after a couple of attempts to rectify the problem, was suggested the movement of my entire development environment to a dedicated virtual machine.&lt;/p&gt;
&lt;p&gt;So, thanks to &lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://dannyamey.com/&quot;&gt;Danny Amey&lt;/a&gt; and &lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://intranation.com&quot;&gt;Brad Wright&lt;/a&gt;, I&amp;#8217;m now running a proper Ubuntu server as my development environment and have just as much control over it as I do on my live web server. In fact, the two are pretty much identical; and, best of all, I have access to all the files on my dev server using VMWare shared folders, which means I can use all my favourite OS X tools to create and edit files. I really can&amp;#8217;t advocate this method enough.&lt;/p&gt;
&lt;p&gt;For more information on creating such an environment, I recommend reading Brad&amp;#8217;s post, &amp;#8220;&lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://intranation.com/entries/2009/03/development-virtual-machines-os-x-using-vmware-and/&quot;&gt;development virtual machines on OS X using VMWare and Ubuntu&lt;/a&gt;&amp;#8220;.&lt;/p&gt;</description>
         <author>Tim</author>
         <guid isPermaLink="false">http://nefariousdesigns.co.uk/archive/2009/04/a-better-os-x-development-environment/</guid>
         <pubDate>Sun, 12 Apr 2009 14:41:44 -0700</pubDate>
      </item>
      <item>
         <title>Web Servers and Email: Postfix on Ubuntu</title>
         <link>http://nefariousdesigns.co.uk/archive/2009/04/web-servers-and-email-postfix-on-ubuntu/</link>
         <description>&lt;p&gt;Setting up web servers is an oft-covered subject in the web development blogosphere. However, when I needed to set up a shared web and &lt;em&gt;email&lt;/em&gt; server, I discovered that such documentation was somewhat more dispersed. With that in mind, and following the development of an email newsletter at work (in which I demonstrated several email testing techniques that were of interest to some of the other developers), I began drafting a blog post that would hopefully bring some of that information together. Sadly, I never finished.&lt;/p&gt;
&lt;p&gt;Due to an ever more stressful workplace and the arrival of another child in the household, I took a somewhat forced break from blogging. This was entirely unintended and I&amp;#8217;ve decided to get back on the wagon again by finishing the aforementioned post.&lt;/p&gt;
&lt;p&gt;So here it is; the finished article on setting up Postfix on a shared mail and web server. Please remember that I&amp;#8217;m technically a mail server numpty and probably won&amp;#8217;t have all the answers to questions should you have them. However, feel free to leave them in the comments and hopefully someone out there (or someone I can poke for comment elsewhere) can help you out.&lt;/p&gt;
&lt;p&gt;&lt;span id=&quot;more-180&quot;&gt;&lt;/span&gt;&lt;/p&gt;
&lt;h2&gt;A bit of background&lt;/h2&gt;
&lt;p&gt;I made the jump from supported, pre-built hosting to entirely self-managed hosting last year. As a result, I soon discovered the need to handle email received by the various hosted domains on my server.&lt;/p&gt;
&lt;p&gt;One solution to this problem would be to use &lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://www.google.com/apps/intl/en/business/index.html&quot;&gt;Google Apps for Business&lt;/a&gt;. Too easy, drill sergeant; and also $50 more than I was willing to spend a year. Another solution would be to install my own email server and manage it myself. Despite this idea giving me The Fear&amp;trade;, it also meant I&amp;#8217;d be learning something new &amp;#8212; a buzz I find difficult to ignore at the best of times.&lt;/p&gt;
&lt;p&gt;Given those options, I&amp;#8217;m sure it&amp;#8217;s not too hard to figure out which route I took, and the following blog post is a small amount of what I learnt in the process.&lt;/p&gt;
&lt;h2&gt;Hostname&lt;/h2&gt;
&lt;p&gt;Often, when building a web server, the server hostname is overlooked as unimportant. This is generally because the DNS system provides all the functionality needed when serving files over HTTP. However, when the server is required to handle email, it is important to set a hostname because it is used by the various email protocols as a source and destination identifier; ergo a key component in the identification of spam.&lt;/p&gt;
&lt;p&gt;Postfix will let you send and receive mail just fine between accounts on a machine with a fantasy name. However, you cannot use a fantasy hostname in your email address when sending email via the Internet, because no-one would be able to reply to your mail. In fact, more and more sites refuse mail addresses with non-existent domain names.&lt;/p&gt;
&lt;p&gt;Further to this, you may want to specify a &lt;em&gt;fully-qualified domain name&lt;/em&gt; hostname. A hostname is considered to be a fully qualified domain name (FQDN) if all the labels up to and including the top-level domain name (TLD) are specified. The hostname &amp;#8220;mail.nerfabulousdesigns.co.uk&amp;#8221; terminates with the top-level domain &amp;#8220;co.uk&amp;#8221; and is thus fully-qualified. Depending on the system, an unqualified hostname such as &amp;#8220;server1&amp;#8243; or &amp;#8220;test-server&amp;#8221; may be combined with default domain names in order to determine the fully qualified domain name. However, in most cases, a web server or mail server won&amp;#8217;t be running in that sort of environment.&lt;/p&gt;
&lt;p&gt;With all that in mind, it&amp;#8217;s best to use a domain name you can access the DNS records for, as you&amp;#8217;ll want to forward email to it using the MX record. An accepted standard, when working with mail, is to use &amp;#8220;mail.mydomain.com&amp;#8221;, however, in this case, we&amp;#8217;re sharing email and web serving duties on the same box. A better solution would be to come up with any name that you can use to uniquely identify the server in your DNS settings. For the purpose of my examples, I&amp;#8217;m going to work with the hostname &amp;#8220;spartacus.nerfabulousdesigns.co.uk&amp;#8221;.&lt;/p&gt;
&lt;h3&gt;DNS for your hostname&lt;/h3&gt;
&lt;p&gt;Before I start wading into the installing and configuring the server, it&amp;#8217;s important to get the DNS set up in your DNS manager. So, if the IP address of our server is 123.456.789.123 we&amp;#8217;ll want the following DNS records:&lt;/p&gt;
&lt;pre&gt;&lt;samp&gt;A Records:
spartacus.nerfabulousdesigns.co.uk -&amp;gt; 123.456.789.123
mail.nerfabulousdesigns.co.uk -&amp;gt; 123.456.789.123 MX Record:
mail.nerfabulousdesigns.co.uk&lt;/samp&gt;&lt;/pre&gt;
&lt;p&gt;Any other domains you want to set up for email only need the following rules:&lt;/p&gt;
&lt;pre&gt;&lt;samp&gt;A Records:
mail.yourdomain.com -&amp;gt; 123.456.789.123 MX Record:
mail.yourdomain.com&lt;/samp&gt;&lt;/pre&gt;
&lt;p&gt;Once you&amp;#8217;ve saved those changes, and you&amp;#8217;re awaiting DNS propagation, it&amp;#8217;s time to get back to our server.&lt;/p&gt;
&lt;h3&gt;Server settings for your hostname&lt;/h3&gt;
&lt;p&gt;To find out the current hostname of your server (which is defined during installation), type the following:&lt;/p&gt;
&lt;pre&gt;&lt;samp&gt;$ &lt;kbd&gt;hostname&lt;/kbd&gt;&lt;/samp&gt;&lt;/pre&gt;
&lt;p&gt;The &lt;code&gt;hostname&lt;/code&gt; command will output the current hostname if you run it without any parameters. If you want to see the fully qualified hostname, type the following:&lt;/p&gt;
&lt;pre&gt;&lt;samp&gt;$ &lt;kbd&gt;hostname -f&lt;/kbd&gt;&lt;/samp&gt;&lt;/pre&gt;
&lt;p&gt;To change your hostname temporarily, you can simply enter the new hostname as the first parameter of the hostname command. So, assuming I want to identify my server as &amp;#8220;spartacus&amp;#8221;, I&amp;#8217;d enter the following:&lt;/p&gt;
&lt;pre&gt;&lt;samp&gt;$ &lt;kbd&gt;hostname spartacus.nerfabulousdesigns.co.uk&lt;/kbd&gt;&lt;/samp&gt;&lt;/pre&gt;
&lt;p&gt;Now we can check our change:&lt;/p&gt;
&lt;pre&gt;&lt;samp&gt;$ &lt;kbd&gt;hostname&lt;/kbd&gt;
spartacus.nerfabulousdesigns.co.uk&lt;/samp&gt;&lt;/pre&gt;
&lt;p&gt;Huzzah!&lt;/p&gt;
&lt;p&gt;Unfortunately, that change will be reset should the machine be rebooted for any reason.&lt;/p&gt;
&lt;p&gt;Not-huzzah!&lt;/p&gt;
&lt;p&gt;To make the change permanent, you&amp;#8217;ll need to edit the single-line &lt;code&gt;/etc/hostname&lt;/code&gt; file:&lt;/p&gt;
&lt;pre&gt;&lt;samp&gt;$ &lt;kbd&gt;sudo vim /etc/hostname&lt;/kbd&gt;&lt;/samp&gt;&lt;/pre&gt;
&lt;p&gt;Update it to contain the following:&lt;/p&gt;
&lt;pre&gt;&lt;samp&gt;spartacus.nerfabulousdesigns.co.uk&lt;/samp&gt;&lt;/pre&gt;
&lt;p&gt;Now you can trigger your change by restarting the hostname daemon:&lt;/p&gt;
&lt;pre&gt;&lt;samp&gt;$ &lt;kbd&gt;/etc/init.d/hostname.sh start&lt;/kbd&gt;&lt;/samp&gt;&lt;/pre&gt;
&lt;p&gt;However, you don&amp;#8217;t need to do that just yet since you&amp;#8217;ll probably want to restart your server later on in the process.&lt;/p&gt;
&lt;h3&gt;The hosts file&lt;/h3&gt;
&lt;p&gt;Next we&amp;#8217;ll need to update the hosts file on the server so that it recognises the new hostname as a referer to the loopback IP 127.0.0.1. To do that, edit the hosts file with the following command:&lt;/p&gt;
&lt;pre&gt;&lt;samp&gt;$ &lt;kbd&gt;sudo vi /etc/hosts&lt;/kbd&gt;&lt;/samp&gt;&lt;/pre&gt;
&lt;p&gt;And then update it so that it contains a line similar to this:&lt;/p&gt;
&lt;pre&gt;&lt;samp&gt;127.0.0.1 spartacus.nerfabulousdesigns.co.uk&lt;/samp&gt;&lt;/pre&gt;
&lt;p&gt;Once this file has been saved, we can do that reboot we were going to do earlier:&lt;/p&gt;
&lt;pre&gt;&lt;samp&gt;$ &lt;kbd&gt;sudo reboot&lt;/kbd&gt;&lt;/samp&gt;&lt;/pre&gt;
&lt;p&gt;Once your server is back up, the hostname change is complete. Your server will now use the loopback address when hostname references are used, instead of wasting valuable time checking DNS records.&lt;/p&gt;
&lt;h2&gt;Install Postfix&lt;/h2&gt;
&lt;p&gt;Now that the server is primed for email, it&amp;#8217;s time to install postfix &amp;#8212; and while we&amp;#8217;re at it, let&amp;#8217;s install mailx, an improved version of the mail email user agent program, and let&amp;#8217;s also confirm we have telnet installed as we&amp;#8217;re going to use it for testing later on:&lt;/p&gt;
&lt;pre&gt;&lt;samp&gt;$ &lt;kbd&gt;sudo aptitude install postfix mailx telnet&lt;/kbd&gt;&lt;/samp&gt;&lt;/pre&gt;
&lt;p&gt;As Postfix installs, you&amp;#8217;ll be asked a number of configuration questions:&lt;/p&gt;
&lt;p&gt;For &amp;#8220;general type of mail configuration&amp;#8221;, choose:&lt;/p&gt;
&lt;pre&gt;&lt;samp&gt;Internet Site&lt;/samp&gt;&lt;/pre&gt;
&lt;p&gt;You will then be asked the fully qualified domain name of your server, which in our case is:&lt;/p&gt;
&lt;pre&gt;&lt;samp&gt;spartacus.nerfabulousdesigns.co.uk&lt;/samp&gt;&lt;/pre&gt;
&lt;p&gt;Once you&amp;#8217;ve done that, the installation is complete. Your web server is now capable of sending email; and to prove it, let&amp;#8217;s just test it from the command line.&lt;/p&gt;
&lt;h2&gt;Testing&lt;/h2&gt;
&lt;p&gt;Let&amp;#8217;s send an email to a real email address (remember to replace &lt;samp&gt;somebody@somewhere.com&lt;/samp&gt; with the real email address of your choice):&lt;/p&gt;
&lt;pre&gt;&lt;samp&gt;$ &lt;kbd&gt;mail somebody@somewhere.com&lt;/kbd&gt;&lt;/samp&gt;&lt;/pre&gt;
&lt;p&gt;The mail program will now ask you for a subject. Once you press return, mail will now be accepting the body of your email (albeit without a prompt). To tell the program that you&amp;#8217;ve reached the end of your email body, you&amp;#8217;ll need to place a single full-stop character, &amp;#8220;.&amp;#8221;, on a line by itself (since the return character is perfectly valid in the body of your mail). Finally, the mail program will then ask you for any CC addresses. &lt;/p&gt;
&lt;p&gt;Here&amp;#8217;s an example of the complete screen output:&lt;/p&gt;
&lt;pre&gt;&lt;samp&gt;$ &lt;kbd&gt;mail somebody@somewhere.com&lt;/kbd&gt;
Subject: &lt;kbd&gt;Testing my all new email server!&lt;/kbd&gt;
&lt;kbd&gt;Red leader, this is mail server. Are you receiving, over?
.&lt;/kbd&gt;
Cc:
$&lt;/samp&gt;&lt;/pre&gt;
&lt;p&gt;You won&amp;#8217;t receive any confirmation that the email has been sent &amp;#8212; you should just return to the command prompt &amp;#8212; however, as long as everything was set up correctly, you should have received the email.&lt;/p&gt;
&lt;p&gt;The next step is to configure our mail server so that it knows what to do with received email.&lt;/p&gt;
&lt;h2&gt;Configuration&lt;/h2&gt;
&lt;p&gt;Configuration of a mail server is where all the pain and torment begins; but in this case, I only want to set up mail forwarding &amp;#8212; which takes all the pain and torment away and leaves us with a fairly straight forward, unburdened mail server that&amp;#8217;s using very little disk space. I could usually do this at the DNS level, but I chose not to in case I decided to work with real mail boxes in the future &amp;#8212; and also because I was still relishing the learning experience. If you want to set up something different, I&amp;#8217;m afraid you&amp;#8217;re going to have to look elsewhere for a tutorial because I haven&amp;#8217;t the time (or the patience) to go through the multitude of different set-ups that are possible.&lt;/p&gt;
&lt;p&gt;The first step in setting up mail forwarding in Postfix is to create a virtual hash. To do that, we need to create the following file:&lt;/p&gt;
&lt;pre&gt;&lt;samp&gt;$ &lt;kbd&gt;sudo vim /etc/postfix/virtual&lt;/kbd&gt;&lt;/samp&gt;&lt;/pre&gt;
&lt;p&gt;And inside that file, we need to define some values. Here&amp;#8217;s how we&amp;#8217;d set up nerfabulousdesigns.co.uk as a mail forwarding domain:&lt;/p&gt;
&lt;pre&gt;&lt;samp&gt;john@nerfabulousdesigns.co.uk john.smith@yahoo.com
joe@nerfabulousdesigns.co.uk joe.bloggs@yahoo.com # For a catch-all, do the following
@nerfabulousdesigns.co.uk example@yahoo.com&lt;/samp&gt;&lt;/pre&gt;
&lt;p&gt;Once you&amp;#8217;ve saved that file, run the following command to create the postmap:&lt;/p&gt;
&lt;pre&gt;&lt;samp&gt;$ &lt;kbd&gt;postmap /etc/postfix/virtual&lt;/kbd&gt;&lt;/samp&gt;&lt;/pre&gt;
&lt;p&gt;Next you&amp;#8217;ll also need to update this file:&lt;/p&gt;
&lt;pre&gt;&lt;samp&gt;$ &lt;kbd&gt;sudo vim /etc/postfix/main.cf&lt;/kbd&gt;&lt;/samp&gt;&lt;/pre&gt;
&lt;p&gt;Add your domain to &lt;code&gt;virtual_alias_domains&lt;/code&gt; and your virtual hash to &lt;code&gt;virtual_alias_maps&lt;/code&gt; like so:&lt;/p&gt;
&lt;pre&gt;&lt;samp&gt;virtual_alias_domains = nerfabulousdesigns.co.uk ...other hosted domains...
virtual_alias_maps = hash:/etc/postfix/virtual&lt;/samp&gt;&lt;/pre&gt;
&lt;p&gt;Finally, you&amp;#8217;ll need to do the following to restart Postfix:&lt;/p&gt;
&lt;pre&gt;&lt;samp&gt;$ &lt;kbd&gt;postfix reload&lt;/kbd&gt;&lt;/samp&gt;&lt;/pre&gt;
&lt;p&gt;Any emails to the domains or addresses you added to the virtual hash should now be forwarded as expected.&lt;/p&gt;
&lt;h2&gt;Telnet&lt;/h2&gt;
&lt;p&gt;Finally, let&amp;#8217;s test the email server is working using Telnet. This is a handy little technique for checking everything is as expected, since it will also display responses at every stage of the mail sending process.&lt;/p&gt;
&lt;p&gt;You can telnet from any machine that has it installed &amp;#8212; and since we installed it on our server earlier, we can even telnet the server to itself, which might be useful when trying to track down problems.&lt;/p&gt;
&lt;p&gt;To begin with, let&amp;#8217;s Telnet to our server over the default SMTP port 25:&lt;/p&gt;
&lt;pre&gt;&lt;samp&gt;$ &lt;kbd&gt;telnet mail.nerfabulousdesigns.co.uk 25&lt;/kbd&gt;&lt;/samp&gt;&lt;/pre&gt;
&lt;p&gt;Which should trigger a response similar to this:&lt;/p&gt;
&lt;pre&gt;&lt;samp&gt;Trying 209.20.86.249...
Connected to mail.nerfabulousdesigns.co.uk.
Escape character is '^]'.
220 spartacus.nerfabulousdesigns.co.uk ESMTP Postfix (Ubuntu)&lt;/samp&gt;&lt;/pre&gt;
&lt;p&gt;If the connection was a success, you should receive a 220 SMTP reply code. For more information, here&amp;#8217;s &lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://www.greenend.org.uk/rjk/2000/05/21/SMTP-replies.html&quot;&gt;a handy reference on SMTP reply codes&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;The next thing we need to do, in the essence of being polite, is greet the mail server. We can do that one of two ways. We can either use the SMTP command, &lt;code&gt;HELO&lt;/code&gt;:&lt;/p&gt;
&lt;pre&gt;&lt;samp&gt;&lt;kbd&gt;HELO my.local.domain&lt;/kbd&gt;
250 spartacus.nerfabulousdesigns.co.uk&lt;/samp&gt;&lt;/pre&gt;
&lt;p&gt;Or we can use the more recent &lt;code&gt;EHLO&lt;/code&gt; command, which will return more detailed information about the server:&lt;/p&gt;
&lt;pre&gt;&lt;samp&gt;&lt;kbd&gt;EHLO my.local.domain&lt;/kbd&gt;
250-spartacus.nerfabulousdesigns.co.uk
â€¦ More detailed info. hereâ€¦&lt;/samp&gt;&lt;/pre&gt;
&lt;p&gt;Great, so now that we&amp;#8217;ve identified ourselves, we&amp;#8217;re reading to start defining the envelope for our message. First, we need to tell the mail server who the sender is:&lt;/p&gt;
&lt;pre&gt;&lt;samp&gt;&lt;kbd&gt;MAIL FROM:&lt;/kbd&gt; 
250 2.1.0 Ok&lt;/samp&gt;&lt;/pre&gt;
&lt;p&gt;Second, we need to tell the mail server who we&amp;#8217;d like the email delivered to:&lt;/p&gt;
&lt;pre&gt;&lt;samp&gt;&lt;kbd&gt;RCPT TO:joe@nerfabulousdesigns.co.uk&lt;/kbd&gt;
250 2.1.5 Ok&lt;/samp&gt;&lt;/pre&gt;
&lt;p&gt;That&amp;#8217;s it; the envelope is now complete. We can now move onto filling our message with data. To do that, we simply use the command &lt;code&gt;DATA&lt;/code&gt;, which will then allow us to enter the subject and main content for our message:&lt;/p&gt;
&lt;pre&gt;&lt;samp&gt;&lt;kbd&gt;DATA&lt;/kbd&gt;
354 End data with . 
&lt;kbd&gt;Subject: Test Email
This is a test email.
.&lt;/kbd&gt;
250 2.0.0 Ok: queued as 40F438D023&lt;/samp&gt;&lt;/pre&gt;
&lt;p&gt;Our message is complete, and has been queued by the mail server for redistribution to the recipient. We&amp;#8217;re done here, so let&amp;#8217;s quite out of the telnet session:&lt;/p&gt;
&lt;pre&gt;&lt;samp&gt;&lt;kbd&gt;QUIT&lt;/kbd&gt;
221 2.0.0 Bye
Connection closed by foreign host.
$ &lt;/samp&gt;&lt;/pre&gt;
&lt;p&gt;And we&amp;#8217;re now back at our original command prompt. If you check the mailbox of your recipient, you should have successfully received the email.&lt;/p&gt;
&lt;h2&gt;Summary&lt;/h2&gt;
&lt;p&gt;Despite the fact that I could probably have handled email in more efficient ways, I thoroughly enjoyed learning about Postfix and the black magic therein. I&amp;#8217;m sure that some of my peers will have plenty to correct me on, and I sincerely hope they do; as previously stated, this was intended as a learning experience, and learning is what I have done.&lt;/p&gt;
&lt;p&gt;Hopefully, some &amp;#8212; if not all &amp;#8212; the techniques used in this article will be of some use to you. Certainly, they have aided me in my understanding of core internet technologies.&lt;/p&gt;
&lt;p&gt;Please feel free to comment, question, or to point out flaws with my methods. I hope the discussion is fruitful.&lt;/p&gt;</description>
         <author>Tim</author>
         <guid isPermaLink="false">http://nefariousdesigns.co.uk/archive/2009/04/web-servers-and-email-postfix-on-ubuntu/</guid>
         <pubDate>Sat, 11 Apr 2009 09:16:39 -0700</pubDate>
      </item>
      <item>
         <title>Practical Django Projects and Django 1.0</title>
         <link>http://nefariousdesigns.co.uk/archive/2008/09/practical-django-projects-and-django-10/</link>
         <description>&lt;p&gt;I recently purchased a copy of &amp;#8220;&lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://www.amazon.co.uk/gp/product/1590599969?ie=UTF8&amp;#038;tag=gamersite-21&amp;#038;linkCode=as2&amp;#038;camp=1634&amp;#038;creative=6738&amp;#038;creativeASIN=1590599969&quot;&gt;Practical Django Projects&lt;/a&gt;&amp;#8220;, by James Bennett, with the intention of diving straight in and learning Django. I&amp;#8217;d prepared for this daring feat of code-ninjutsu [yes, that's the correct spelling] with a crash course in Python via &amp;#8220;&lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://www.amazon.co.uk/gp/product/1590593561?ie=UTF8&amp;#038;tag=gamersite-21&amp;#038;linkCode=as2&amp;#038;camp=1634&amp;#038;creative=6738&amp;#038;creativeASIN=1590593561&quot;&gt;Dive Into Python&lt;/a&gt;&amp;#8220;, by Mark Pilgrim.&lt;/p&gt;
&lt;p&gt;This appears to have been the correct choice, as I&amp;#8217;ve already acquired a confident grasp of the concepts and techniques of Django in less than a few days of playing with it (granted; with the odd reference look-up on &lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://www.djangobook.com/&quot;&gt;http://www.djangobook.com/&lt;/a&gt; and &lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://docs.djangoproject.com/en/dev/&quot;&gt;http://docs.djangoproject.com/en/dev/&lt;/a&gt;).&lt;/p&gt;
&lt;p&gt;However, last night it all went a bit wrong when I upgraded my local version of Django from 0.96 to 1.0&amp;hellip;&lt;/p&gt;
&lt;p&gt;&lt;span id=&quot;more-179&quot;&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;Most of my issues were due to the fact that some of the code in the examples, included in &lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://www.amazon.co.uk/gp/product/1590599969?ie=UTF8&amp;#038;tag=gamersite-21&amp;#038;linkCode=as2&amp;#038;camp=1634&amp;#038;creative=6738&amp;#038;creativeASIN=1590599969&quot;&gt;Practical Django Projects&lt;/a&gt;, was now out of date. However, I had expected this (thanks to warnings from &lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://cyril.doussin.name/&quot;&gt;Cyril Doussin&lt;/a&gt; and &lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://dynamicflash.com/&quot;&gt;Steve Webster&lt;/a&gt;) and went about fixing the problems using the informative &lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://docs.djangoproject.com/en/dev/releases/1.0-porting-guide/&quot;&gt;Porting Guide on the Django documentation site&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Following my extensive fixes, I was still experiencing issues when decoupling the Admin class from its relevant model. In most cases, this was a relatively easy process, but in one particular situation, where I had used &lt;code&gt;edit_inline&lt;/code&gt; and needed to update the method to use the new InlineModelAdmin objects, I had a slightly confusing issue: I needed to add the InlineModelAdmin object to one of the django.contrib applications â€” FlatPage â€” to get the SearchKeyword application to work.&lt;/p&gt;
&lt;p&gt;After a short period googling, I found an interesting, well-written blog post by &lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://jasonism.org/&quot;&gt;Jason Broyles&lt;/a&gt;, &amp;#8220;&lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://jasonism.org/weblog/2008/aug/04/adding-inlinemodeladmin-djangocontrib-application/&quot;&gt;Add InlineModelAdmin to a django.contrib app&lt;/a&gt;&amp;#8220;. Unsurprisingly, it seemed others had had exactly the same issue.&lt;/p&gt;
&lt;p&gt;Jason&amp;#8217;s final model.py and admin.py files were as follows:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;# models.py from django.db import models
from django.contrib.flatpages.models import FlatPage class SearchKeyword(models.Model): keyword = models.CharField(max_length=50) page = models.ForeignKey(FlatPage) def __unicode__(self): return self.keyword&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;# admin.py from django.contrib import admin
from cms.search.models import SearchKeyword
from django.contrib.flatpages.models import FlatPage
from django.utils.translation import ugettext_lazy as _ class SearchKeywordInline(admin.StackedInline): model = SearchKeyword extra = 3 max_num = 6 class FlatPageAdmin(admin.ModelAdmin): fieldsets = ( (None, {'fields': ('url', 'title', 'content', 'sites')}), (_('Advanced options'), {'classes': ('collapse',), 'fields': ('enable_comments', 'registration_required', 'template_name')}), ) list_display = ('url', 'title') list_filter = ('sites', 'enable_comments', 'registration_required') search_fields = ('url', 'title') inlines = [SearchKeywordInline,] admin.site.unregister(FlatPage)
admin.site.register(FlatPage, FlatPageAdmin)&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Jason followed these examples with the following explanation:&lt;/p&gt;
&lt;blockquote cite=&quot;http://jasonism.org/weblog/2008/aug/04/adding-inlinemodeladmin-djangocontrib-application/&quot;&gt;&lt;p&gt;The above admin.py file will make it so the SearchKeyword model is accessible in the FlatPages admin interface. It does this by first creating the SearchKeywordInline class and adding it to a new FlatPage ModelAdmin function. I also didn&amp;#8217;t want to loose out on any of the extra options from the default django.contrib.flatpages ModelAdmin so I copied lines 6 and 14-20 from it and added the code to my file. Line 23 then unregisters the default FlatPage ModelAdmin and line 24 registers this new one with my inlines included.&lt;/p&gt;&lt;/blockquote&gt;
&lt;p&gt;This solution fixed my problems, however I was concerned that copying and pasting code from &lt;code&gt;django.contrib.flatpages ModelAdmin&lt;/code&gt; to &lt;code&gt;admin.py&lt;/code&gt; was a massively inelegant solution. With that in mind, I came up with the following solution using inheritance:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;# admin.py from django.contrib import admin
from cms.search.models import SearchKeyword
from django.contrib.flatpages.models import FlatPage
from django.contrib.flatpages.admin import FlatPageAdmin
from django.utils.translation import ugettext_lazy as _ class SearchKeyword_Inline(admin.TabularInline): model = SearchKeyword extra = 3 max_num = 6 class FlatPageAdmin(FlatPageAdmin): inlines = [SearchKeyword_Inline] admin.site.unregister(FlatPage)
admin.site.register(FlatPage, FlatPageAdmin)&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This worked perfectly.&lt;/p&gt;
&lt;p&gt;As a final note, I&amp;#8217;d just like to thank Jason for posting his solution; without that much needed information, I probably would have spent a lot more time trying to fix the issue than was really required. It just goes to show that developers that blog are a huge benefit to confused developers everywhere.&lt;/p&gt;</description>
         <author>Tim</author>
         <guid isPermaLink="false">http://nefariousdesigns.co.uk/archive/2008/09/practical-django-projects-and-django-10/</guid>
         <pubDate>Thu, 25 Sep 2008 02:41:46 -0700</pubDate>
      </item>
      <item>
         <title>The Joy of UNIX</title>
         <link>http://nefariousdesigns.co.uk/archive/2008/09/the-joy-of-unix/</link>
         <description>&lt;p&gt;One of the best things about developing from a Mac is the fact that it is a UNIX-based operating system. This means that my development environment is a far closer match to my production hosting environment (Linux) than it was when I was developing under Windows.&lt;/p&gt;
&lt;p&gt;The net result of this shift in paradigm is a rapidly expanding knowledge of the command-set and OS structure. The exposure to UNIX has done me the world of good; particularly in regard to web development and server management. Sadly, the relative shelter I was accustomed to at Rentokil Initial, thanks to the inclusion of immensely talented and helpful server admins within our team, had hindered my development as a web developer, and provoked ridicule at the hands of my fellow Y! EU developers (in the nicest possible way, of course).&lt;/p&gt;
&lt;p&gt;With all that in mind, here&amp;#8217;s a bunch of stuff I&amp;#8217;ve learnt that might be a useful reference resource&amp;hellip;&lt;/p&gt;
&lt;p&gt;&lt;span id=&quot;more-176&quot;&gt;&lt;/span&gt;&lt;/p&gt;
&lt;h2&gt;Books&lt;/h2&gt;
&lt;p&gt;&lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://www.amazon.co.uk/gp/product/013937681X?ie=UTF8&amp;#038;tag=gamersite-21&amp;#038;linkCode=as2&amp;#038;camp=1634&amp;#038;creative=6738&amp;#038;creativeASIN=013937681X&quot;&gt;&lt;img src='http://nefariousdesigns.co.uk/blog/images/41qm4speaal_sl160_.jpg' alt='' class='pos1 framed'/&gt;&lt;/a&gt; The first book I&amp;#8217;d recommend reading for a good grounding in UNIX is &amp;#8220;&lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://www.amazon.co.uk/gp/redirect.html?ie=UTF8&amp;#038;location=http%3A%2F%2Fwww.amazon.co.uk%2FUnix-Programming-Environment-Prentice-Hall-Software%2Fdp%2F013937681X%3Fie%3DUTF8%26s%3Dbooks%26qid%3D1222162055%26sr%3D8-1&amp;#038;tag=gamersite-21&amp;#038;linkCode=ur2&amp;#038;camp=1634&amp;#038;creative=6738&quot;&gt;&lt;strong&gt;The UNIX Programming Environment&lt;/strong&gt;&lt;/a&gt;&amp;#8220;, by Brian W. Kernighan and Rob Pike. Although this is book is over 20 years old, it&amp;#8217;s still highly relevant; Kernighan and Pike both worked at Bell Labs during the development of UNIX and contributed greatly to the OS and its school of thought. The book covers a huge expanse of subjects, from the basics through to full program development.&lt;/p&gt;
&lt;p&gt;&lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://www.amazon.co.uk/gp/product/0596100299?ie=UTF8&amp;#038;tag=gamersite-21&amp;#038;linkCode=as2&amp;#038;camp=1634&amp;#038;creative=6738&amp;#038;creativeASIN=0596100299&quot;&gt;&lt;img src=&quot;http://nefariousdesigns.co.uk/blog/images/51w740pbx7l_sl160_.thumbnail.jpg&quot; alt=&quot;&quot; class=&quot;pos2 framed&quot;/&gt;&lt;/a&gt;The second book, as is so often the case, is published by O&amp;#8217;Reilly. &amp;#8220;&lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://www.amazon.co.uk/gp/product/0596100299?ie=UTF8&amp;#038;tag=gamersite-21&amp;#038;linkCode=as2&amp;#038;camp=1634&amp;#038;creative=6738&amp;#038;creativeASIN=0596100299&quot;&gt;&lt;strong&gt;UNIX in a Nutshell&lt;/strong&gt;&lt;/a&gt;&amp;#8220;, by Arnold Robbins, is a great, up-to-date examination of the operating system, including a vast array of information perfect for beginners and experienced users alike.&lt;/p&gt;
&lt;p&gt;Both of these books should provide enough knowledge for you to feel safe getting down and dirty with UNIX; so let&amp;#8217;s dive in with a look at some useful keyboard and command line shortcuts:&lt;/p&gt;
&lt;h2&gt;Keyboard and Command Line Shortcuts&lt;/h2&gt;
&lt;p&gt;The following are common keyboard and command line shortcuts for use in UNIX-based systems. Please note that all UNIX variants differ and some of these shortcuts may not be available to you, or may require different syntax or keystrokes.&lt;/p&gt;
&lt;h3&gt;Keyboard Shortcuts&lt;/h3&gt;
&lt;p&gt;To begin with, here&amp;#8217;s a list of useful keyboard shortcuts:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;kbd&gt;CTRL + A&lt;/kbd&gt; â€” Moves the cursor to the beginning of the line.&lt;/li&gt;
&lt;li&gt;&lt;kbd&gt;CTRL + E&lt;/kbd&gt; â€” Moves the cursor to the end of the line.&lt;/li&gt;
&lt;li&gt;&lt;kbd&gt;CTRL + U&lt;/kbd&gt; â€” Erases the complete line.&lt;/li&gt;
&lt;li&gt;&lt;kbd&gt;CTRL + B&lt;/kbd&gt; â€” Moves the cursor backward one character.&lt;/li&gt;
&lt;li&gt;&lt;kbd&gt;CTRL + F&lt;/kbd&gt; â€” Moves the cursor forward one character.&lt;/li&gt;
&lt;li&gt;&lt;kbd&gt;CTRL + H&lt;/kbd&gt; â€” Erase one character. Similar to pressing backspace.&lt;/li&gt;
&lt;li&gt;&lt;kbd&gt;CTRL + W&lt;/kbd&gt; â€” Deletes the last word typed.&lt;/li&gt;
&lt;li&gt;&lt;kbd&gt;CTRL + C&lt;/kbd&gt; â€” Cancels the currently running command.&lt;/li&gt;
&lt;li&gt;&lt;kbd&gt;CTRL + D&lt;/kbd&gt; â€” Logs out of the current session.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Most of those are self-explanatory, but you&amp;#8217;ll wonder how you lived without them soon enough.&lt;/p&gt;
&lt;h3&gt;Command Line Shortcuts&lt;/h3&gt;
&lt;p&gt;Next, let&amp;#8217;s take a look at some useful command line shortcuts, starting with &lt;em&gt;directory navigation&lt;/em&gt;:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;~&lt;/code&gt; â€” References the current user&amp;#8217;s home directory.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;.&lt;/code&gt; â€” References the current directory.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;..&lt;/code&gt; â€” References the parent of the current directory.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Here&amp;#8217;s a quick demonstration to hopefully make their use a little clearer (the names have been changed to protect the innocent). Note, this example uses several UNIX commands; &lt;code&gt;cd&lt;/code&gt; = change directory, &lt;code&gt;pwd&lt;/code&gt; = print working directory, &lt;code&gt;ls&lt;/code&gt; = list contents of directory, and &lt;code&gt;cp&lt;/code&gt; = copy files:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;$ pwd
/Users/timbo
$ cd /var/www/nefarious/
$ pwd
/var/www/nefarious
$ cd ..
$ pwd
/var/www
$ ls
a-website another-website nefarious
$ cd /var/www2
$ pwd
/var/www2
$ ls
$ cp /var/www/* ./
$ ls
a-website another-website nefarious
$ cd ~
$ pwd
/Users/timbo&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Now that we can effectively navigate the directory structure, let&amp;#8217;s have a look at the incredibly useful history utility and its command line shortcuts:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;!!&lt;/code&gt; â€” Re-run your last command.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;!10&lt;/code&gt; â€” Re-run line number 10 in the history.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;!-n&lt;/code&gt; â€” Refer to the current command line minus n.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;!?str?&lt;/code&gt; â€” Refer to the most recent command containing str (string).&lt;/li&gt;
&lt;li&gt;&lt;code&gt;!str&lt;/code&gt; â€” Re-run the last command ran that started with str (string).&lt;/li&gt;
&lt;li&gt;&lt;code&gt;!$&lt;/code&gt; â€” Re-use the parameters from the previous command.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;I won&amp;#8217;t go into detail on each one of those, but here&amp;#8217;s an example of the last one â€” arguably the most useful â€” in action:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;$ pwd
/Users/timbo
$ ls projects/django/
cms coltrane davis
$ cd !$
cd projects/django/
$ pwd
/Users/timbo/projects/django&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;Summary&lt;/h2&gt;
&lt;p&gt;This is just a quick reference to some useful shortcuts; I could have delved deeper into setting up aliases in your profiles and making your prompt look pretty, but I thought I&amp;#8217;d save that for a possible follow up post.&lt;/p&gt;
&lt;p&gt;I hope somebody out there finds this useful; and feel free to add your own tips and tricks in the comments.&lt;/p&gt;</description>
         <author>Tim</author>
         <guid isPermaLink="false">http://nefariousdesigns.co.uk/archive/2008/09/the-joy-of-unix/</guid>
         <pubDate>Tue, 23 Sep 2008 05:33:20 -0700</pubDate>
      </item>
      <item>
         <title>Back on the horse</title>
         <link>http://nefariousdesigns.co.uk/archive/2008/08/back-on-the-horse/</link>
         <description>&lt;p&gt;Right then. After almost a years hiatus, it&amp;#8217;s about time I got back into this blogging lark. Unfortunately, I have a plethora of subjects I&amp;#8217;d like to cover and no idea where to start!&lt;/p&gt;
&lt;p&gt;I think I&amp;#8217;ll get the personal stuff out of the way first and then I can think about planning the web development stuff&amp;hellip;&lt;/p&gt;
&lt;p&gt;&lt;span id=&quot;more-175&quot;&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;The biggest news is that &lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://flickr.com/photos/nefarioustim/2587002110/&quot;&gt;I&amp;#8217;m going to be a father again&lt;/a&gt;, but thankfully this time it&amp;#8217;s just the one baby. Further to that, my twin girls are now 14 months old and &lt;em&gt;extremely&lt;/em&gt; mobile (in horizontal &lt;em&gt;and&lt;/em&gt; vertical directions &amp;#8212; we&amp;#8217;ve had to rearrange the furniture to discourage climbing).&lt;/p&gt;
&lt;p&gt;I&amp;#8217;m still working at &lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://www.yahoo.co.uk&quot;&gt;Yahoo!&lt;/a&gt; in London and, despite the odd crisis of morale, am still enjoying working with what is arguably the best corporate web development team in the world. It&amp;#8217;s a shame my commute is 2 hours each way otherwise I&amp;#8217;d also be enjoying the more social aspects of the team as well (but since most evenings are spent on &lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://www.xbox.com&quot;&gt;Xbox Live&lt;/a&gt; with my colleagues, I&amp;#8217;m not missing &lt;em&gt;too&lt;/em&gt; much).&lt;/p&gt;
&lt;p&gt;I also found out that I have &lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://en.wikipedia.org/wiki/Coeliac_disease&quot;&gt;Coeliac Disease&lt;/a&gt;; a harsh name for what is, effectively, an allergy to gluten (found in wheat, barley, oats, and rye). This hasn&amp;#8217;t been all that difficult to adapt to since my sister has been diagnosed since she was 3 years old &amp;#8212 ;and my dad worked out, shortly after she was diagnosed, that he is too. This basically means that I&amp;#8217;ve been used to shopping, cooking, and dining-out with Coeliacs since a very early age. Want to know the worst part of the allergy? I can no longer drink beer. Sweet, sweet beer. I really miss a tasty pint of &lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://www.guinness.com&quot;&gt;Guinness&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Finally, I&amp;#8217;ve also undertaken a few personal projects: a new rock band, a (possible) book on web development, a cooking blog (no link because it&amp;#8217;s not up yet), and various other things.&lt;/p&gt;
&lt;p&gt;So that&amp;#8217;s the past year in a nutshell. I&amp;#8217;m sure there&amp;#8217;s lots more I could&amp;#8217;ve written but it&amp;#8217;s easier to just condense. Now I can get started on the web development related blog posts&amp;hellip;&lt;/p&gt;
&lt;p&gt;&amp;hellip; although I &lt;em&gt;still&lt;/em&gt; have no idea where to start!&lt;/p&gt;</description>
         <author>Tim</author>
         <guid isPermaLink="false">http://nefariousdesigns.co.uk/archive/2008/08/back-on-the-horse/</guid>
         <pubDate>Sun, 10 Aug 2008 04:03:01 -0700</pubDate>
      </item>
      <item>
         <title>Decade</title>
         <link>http://feedproxy.google.com/~r/crisisaverted/~3/AuDRDVwZVoE/decade</link>
         <description>&lt;p&gt;Ten years ago today I registered socket7.net. It began hosted on a linux box in my closet for a good 2-3 years before finally landing on Dreamhost. It was the crux of teaching myself more about the web. Through it I expanded my knowledge of HTML, CSS, JavaScript, PHP and MySQL; not to mention everything behind the scenes like Apache, DNS, etc.&lt;/p&gt; &lt;p&gt;One year is an eternity on the internet. Hell, even a few days after something big breaks on the 'net if someone mentions it for the first time they get lambasted for reporting &quot;old news.&quot; Ten years, then, is almost unquantifiable by those standards. So much has changed, and so much more will change in the next ten years.&lt;/p&gt; &lt;p&gt;As much as I tend to neglect the site lately, there's no denying that I wouldn't be who I am today without it. Here's to you, socket7.net. May you live another ten years on the web.&lt;/p&gt;&lt;img src=&quot;http://feeds.feedburner.com/~r/crisisaverted/~4/AuDRDVwZVoE&quot; height=&quot;1&quot; width=&quot;1&quot;/&gt;</description>
         <guid isPermaLink="false">http://socket7.net/article/decade</guid>
         <pubDate>Mon, 16 Nov 2009 09:32:05 -0800</pubDate>
      </item>
      <item>
         <title>IE VPC Images now with WGA</title>
         <link>http://feedproxy.google.com/~r/crisisaverted/~3/gNRG8gp0SdQ/ie-vpc-images-now-with-wga</link>
         <description>&lt;p&gt;Just when I was on a virtualization roll &lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://socket7.net/article/how-to-run-ie-on-your-mac-with-virtualbox/&quot;&gt;using VirtualBox for testing IE on my Mac&lt;/a&gt;, Microsoft stopped me dead in my tracks. The latest version of &lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://www.microsoft.com/downloads/details.aspx?FamilyID=21eabb90-958f-4b64-b5f1-73d0a413c8ef&amp;displaylang=en&quot;&gt;Internet Explorer Application Compatibility VPC Images&lt;/a&gt; now have the anti-piracy features of Windows Genuine Advantage enabled.&lt;/p&gt; &lt;p&gt;The hardware signature detected when a VPC image first boots in a non-VPC host is different from the signature present when the image was first created, presumably in VPC. This difference triggers WGA's re-activation requirement to make sure you're not a dirty pirate. Of course you're not a dirty pirate, but if you wish to re-activate Windows you're going to need the original Windows Product Key which isn't provided with the VPC images. Microsoft has effectively blocked end users from hosting the VPC images with anything but Virtual PC.&lt;/p&gt; &lt;p&gt;To their credit, Microsoft has done a great thing by providing these VPC images free of charge, and it makes sense they would use their own virtual disk format for distribution. But it doesn't make sense for them to deny non-Windows (thus, non-VPC users) the ability to use the images.&lt;/p&gt; &lt;p&gt;One of the largest complaints I hear from web developers who work in a non-Windows environment is the difficulty of testing in IE. Until recently, VirtualBox was working quite nicely for me in this regard. Microsoft would be doing another great thing by loosening the reigns a bit. Alternatively, they could release Virtual PC for other operating systems.&lt;/p&gt;&lt;img src=&quot;http://feeds.feedburner.com/~r/crisisaverted/~4/gNRG8gp0SdQ&quot; height=&quot;1&quot; width=&quot;1&quot;/&gt;</description>
         <guid isPermaLink="false">http://socket7.net/article/ie-vpc-images-now-with-wga</guid>
         <pubDate>Wed, 09 Sep 2009 12:38:23 -0700</pubDate>
      </item>
      <item>
         <title>How to run IE on your Mac with VirtualBox</title>
         <link>http://feedproxy.google.com/~r/crisisaverted/~3/Ua2GP8YdIPw/how-to-run-ie-on-your-mac-with-virtualbox</link>
         <description>&lt;p&gt;Recently at work I've switched from Parallels to &lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://www.virtualbox.org/&quot;&gt;VirtualBox&lt;/a&gt; for my virtualization needs. VirtualBox has come a long way recently, and I'm very pleased with its performance and ease of use. Parallels was starting to become noticeably slow, and was generally not working well for me anymore.&lt;/p&gt; &lt;p&gt;At first, I tried to convert my Parallels (.hdd) images to VM Ware (.vmdk) format, which is natively supported in VirtualBox. Virtual PC (.vhd) format is also natively supported. Since my Parallels images are fully licensed versions of Windows XP, I didn't want them to go to waste. Sadly, the 'converted' images were corrupt and weren't recognized by VirtualBox, and I ended up wasting several hours.&lt;/p&gt; &lt;p&gt;I decided to ignore Parallels completely and simply use the free Internet Explorer Application Compatibility VPC Images from Microsoft. I should have done this in the first place, because setting them up was a breeze with the help of the internet and a few helpful how-to articles I found. I could link to those how-to's here but instead I wanted to post my own condensed version of the steps I took setting everything up. Mainly for myself for future reference.&lt;/p&gt; &lt;h3&gt;Step 1&lt;/h3&gt;
&lt;p&gt;Download and install &lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://www.virtualbox.org/wiki/Downloads&quot;&gt;VirtualBox&lt;/a&gt; and &lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://www.apple.com/downloads/macosx/system_disk_utilities/stuffitexpander.html&quot;&gt;Stuffit Expander&lt;/a&gt;. You can skip Stuffit Expander if you already have a tool for opening self-extracting .exe files.&lt;/p&gt; &lt;h3&gt;Step 2&lt;/h3&gt;
&lt;p&gt;Download the free Windows XP &lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://www.microsoft.com/downloads/details.aspx?FamilyID=21eabb90-958f-4b64-b5f1-73d0a413c8ef&amp;displaylang=en&quot;&gt;IE App Compat VPC images&lt;/a&gt; that you'll need and extract the .vhd images with Stuffit Expander (or your tool of choice).&lt;/p&gt; &lt;p&gt;Using Finder, navigate to /Library/VirtualBox and create a new folder for each image. Move the extracted .vhd files into these new folders.&lt;/p&gt; &lt;h3&gt;Step 3&lt;/h3&gt;
&lt;p&gt;In Terminal, run the following for each image:
&lt;pre&gt;
cd /Library/VirtualBox/&amp;lt;image&amp;gt;
VBoxManage internalcommands sethduuid &amp;lt;image&amp;gt;.vhd
&lt;/pre&gt; &lt;p&gt;This undocumented command will avoid UUID conflicts when creating multiple VMs. If you're only setting up one VM, you can skip this.&lt;/p&gt; &lt;h3&gt;Step 4&lt;/h3&gt;
&lt;p&gt;In VirtualBox, create a new Windows XP VM and follow the prompts. When asked, choose &lt;i&gt;Use existing hard disk.&lt;/i&gt; Click the folder icon to open the Virtual Media Manager. Click &lt;i&gt;Add&lt;/i&gt; and navigate to a .vhd file you extracted and relocated in step 2. Click &lt;i&gt;Select&lt;/i&gt; to choose the new virtual disk. Finally, click &lt;i&gt;Next&lt;/i&gt; then &lt;i&gt;Finish&lt;/i&gt;.&lt;/p&gt; &lt;h3&gt;Step 5&lt;/h3&gt;
&lt;p&gt;Start your new VM. Close/cancel any Windows popups or dialogs that appear. There will be quite a few.&lt;/p&gt; &lt;p&gt;From the VirtualBox VM menu bar in OS X select &lt;i&gt;Devices &amp;gt; Install Guest Additions...&lt;/i&gt; and follow the Windows prompts. Reboot Windows when asked.&lt;/p&gt; &lt;h3&gt;Step 6&lt;/h3&gt;
&lt;p&gt;Now it's time to install the network drivers. Why this isn't covered by the VirtualBox Guest Additions is beyond me.&lt;/p&gt; &lt;p&gt;In Windows go to &lt;i&gt;Start &amp;gt; Run...&lt;/i&gt; and run the following:
&lt;pre&gt;D:&amp;#92;VBoxWindowsAdditions-x86.exe /extract /D=C:&amp;#92;Drivers&lt;/pre&gt;
&lt;p&gt;Back to &lt;i&gt;Start &amp;gt; Run...&lt;/i&gt; and run:&lt;/p&gt;
&lt;pre&gt;devmgmt.msc&lt;/pre&gt; &lt;p&gt;In Device Manager, find &lt;i&gt;Network adapters &amp;gt; Ethernet controller&lt;/i&gt;. Right click it, and select &lt;i&gt;Update Driver...&lt;/i&gt;.&lt;/p&gt; &lt;p&gt;In the Hardware Update Wizard choose &lt;i&gt;No, not this time&lt;/i&gt; and click &lt;i&gt;Next&lt;/i&gt;. Select &lt;i&gt;Install from a list or specific location&lt;/i&gt; and click &lt;i&gt;Next&lt;/i&gt;. Check the option &lt;i&gt;Include this location in the search&lt;/i&gt; and paste the following into the Location box:&lt;/p&gt;
&lt;pre&gt;C:&amp;#92;Drivers&amp;#92;x86&amp;#92;Network&amp;#92;AMD&lt;/pre&gt; &lt;p&gt;Alternatively, you can choose &lt;i&gt;Don't search ...&lt;/i&gt; and navigate to the location manually. Click &lt;i&gt;Finish&lt;/i&gt; and you should have a working network connection.&lt;/p&gt; &lt;h3&gt;Step 7&lt;/h3&gt;
&lt;p&gt;In Device Manager, find &lt;i&gt;Batteries &amp;gt; Unknown device&lt;/i&gt;. In my case, there were two. Right click each and select &lt;i&gt;Disable&lt;/i&gt; and confirm. These appear to be VirtualPC specific. In any case, they aren't really necessary anyway.&lt;/p&gt; &lt;p&gt;Next find &lt;i&gt;Universal Serial Bus controllers &amp;gt; Universal Serial Bus (USB) Controller&lt;/i&gt;. Again, there were two. Disable them as well.&lt;/p&gt; &lt;p&gt;Finally, find &lt;i&gt;Sound, video and game controllers &amp;gt; Multimedia Audio Controller&lt;/i&gt; and disable it.&lt;/p&gt; &lt;p&gt;Repeat steps 4-7 to set up additional VMs, and enjoy your new VirtualBox goodness.&lt;/p&gt;&lt;img src=&quot;http://feeds.feedburner.com/~r/crisisaverted/~4/Ua2GP8YdIPw&quot; height=&quot;1&quot; width=&quot;1&quot;/&gt;</description>
         <guid isPermaLink="false">http://socket7.net/article/how-to-run-ie-on-your-mac-with-virtualbox</guid>
         <pubDate>Tue, 11 Aug 2009 17:02:14 -0700</pubDate>
      </item>
      <item>
         <title>Jabber::Bot now on GitHub</title>
         <link>http://feedproxy.google.com/~r/crisisaverted/~3/pc4kiRz2ri0/jabberbot-now-on-github</link>
         <description>&lt;p&gt;I've finally gotten around to tossing &lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://github.com/brettstimmerman/jabber-bot&quot;&gt;Jabber::Bot up on GitHub&lt;/a&gt;. There have been several requests in the past few months to add group chat support and other features, and I haven't had time to look into it. I've even had some patches sent via email that I haven't been able to get to (thanks Matt!).&lt;/p&gt; &lt;p&gt;Perhaps the magical powers of GitHub can give Jabber::Bot a new life.&lt;/p&gt;&lt;img src=&quot;http://feeds.feedburner.com/~r/crisisaverted/~4/pc4kiRz2ri0&quot; height=&quot;1&quot; width=&quot;1&quot;/&gt;</description>
         <guid isPermaLink="false">http://socket7.net/article/jabberbot-now-on-github</guid>
         <pubDate>Wed, 25 Feb 2009 16:11:33 -0800</pubDate>
      </item>
      <item>
         <title>Kick ass wisely.</title>
         <link>http://feedproxy.google.com/~r/crisisaverted/~3/gf2qQCh95Lk/kick-ass-wisely</link>
         <description>&lt;p&gt;Looking at the archives here, it's become obvious I've nearly forgotten how to blog since starting at Yahoo! almost a year and a half ago. It's not that I haven't been doing anything interesting, or come across interesting things to talk about &amp;mdash; far from it.&lt;/p&gt; &lt;p&gt;I've been doing and seeing some of the most amazing things I've ever done or seen, from a career perspective. But, I have found that doing kick ass things at work has made me less likely to do kick ass things while not at work. And those non-work kick ass things are what I used to like to blog about. Doing kick ass things is a tons of fun, but it takes a lot of effort. One shouldn't do kick ass things all the time, or else one might run out of ass to kick. So I save my ass kicking energy for the asses that most need kicking.&lt;/p&gt; &lt;p&gt;Most of my time since joining Yahoo! has been spent working on &lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://developer.yahoo.com/searchmonkey/&quot;&gt;SearchMonkey&lt;/a&gt;, and jumping between various other kick ass projects. Of course, there have also been a good number of not so kick ass projects. Again, it's important to not run out of ass to kick, or energy to kick ass. On top of that, be sure to kick the right ass, not just any old ass that comes along. Even if an ass appears to be begging you to kick it. Even if it offers you cash. Even if peer pressure makes you feel like you'd be less kick ass if you didn't kick this particular ass. There's not much worse than a wasted or misplaced ass kick. Kick ass wisely.&lt;/p&gt; &lt;p&gt;Anyway, late last year I had decided this here blog could use a redesign, and I could use a swift kick in the ass to get things moving again. But, now I'm not so sure. I haven't blogged because I haven't had anything much to say, and that's fine. Despite the kick ass things going on at work I just haven't found myself thinking, &quot;Hey, I should blog about this!&quot; The day I do have something to say (like today) it'll still be here waiting. In the meantime, for all the little blips of life from &quot;whoa&quot; to &quot;wtf&quot; there's always &lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://twitter.com/bretts&quot;&gt;Twitter&lt;/a&gt;.&lt;/p&gt;&lt;img src=&quot;http://feeds.feedburner.com/~r/crisisaverted/~4/gf2qQCh95Lk&quot; height=&quot;1&quot; width=&quot;1&quot;/&gt;</description>
         <guid isPermaLink="false">http://socket7.net/article/kick-ass-wisely</guid>
         <pubDate>Thu, 12 Feb 2009 17:47:22 -0800</pubDate>
      </item>
      <item>
         <title>Links for 2008-12-17 [del.icio.us]</title>
         <link>http://feedproxy.google.com/~r/crisisaverted/~3/C9YbI3fDUUQ/bws</link>
         <description>&lt;ul&gt;
&lt;li&gt;&lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://laconi.ca/trac/&quot;&gt;Laconica&lt;/a&gt;&lt;br/&gt;
Open source Twitter clone.&lt;/li&gt;
&lt;/ul&gt;&lt;img src=&quot;http://feeds.feedburner.com/~r/crisisaverted/~4/C9YbI3fDUUQ&quot; height=&quot;1&quot; width=&quot;1&quot;/&gt;</description>
         <guid isPermaLink="false">http://del.icio.us/bws#2008-12-17</guid>
         <pubDate>Thu, 18 Dec 2008 00:00:00 -0800</pubDate>
      </item>
      <item>
         <title>Links for 2008-10-28 [del.icio.us]</title>
         <link>http://feedproxy.google.com/~r/crisisaverted/~3/Sz3BVA4XiTc/bws</link>
         <description>&lt;ul&gt;
&lt;li&gt;&lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://www.jnack.com/adobe/photoshop/fountain/&quot;&gt;They were all in love with life, drinking from a fountain...&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;&lt;img src=&quot;http://feeds.feedburner.com/~r/crisisaverted/~4/Sz3BVA4XiTc&quot; height=&quot;1&quot; width=&quot;1&quot;/&gt;</description>
         <guid isPermaLink="false">http://del.icio.us/bws#2008-10-28</guid>
         <pubDate>Wed, 29 Oct 2008 00:00:00 -0700</pubDate>
      </item>
      <item>
         <title>Links for 2008-10-15 [del.icio.us]</title>
         <link>http://feedproxy.google.com/~r/crisisaverted/~3/2BzZ3fq_eiQ/bws</link>
         <description>&lt;ul&gt;
&lt;li&gt;&lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://www.gscottolson.com/blackbirdjs/&quot;&gt;Blackbird - Open Source JavaScript Logging Utility&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;&lt;img src=&quot;http://feeds.feedburner.com/~r/crisisaverted/~4/2BzZ3fq_eiQ&quot; height=&quot;1&quot; width=&quot;1&quot;/&gt;</description>
         <guid isPermaLink="false">http://del.icio.us/bws#2008-10-15</guid>
         <pubDate>Thu, 16 Oct 2008 00:00:00 -0700</pubDate>
      </item>
      <item>
         <title>Links for 2008-09-08 [del.icio.us]</title>
         <link>http://feedproxy.google.com/~r/crisisaverted/~3/26M4bc5SSXM/bws</link>
         <description>&lt;ul&gt;
&lt;li&gt;&lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://www.typechart.com/&quot;&gt;Typechart&lt;/a&gt;&lt;br/&gt;
CSS generator for pretty web typefaces.&lt;/li&gt;
&lt;/ul&gt;&lt;img src=&quot;http://feeds.feedburner.com/~r/crisisaverted/~4/26M4bc5SSXM&quot; height=&quot;1&quot; width=&quot;1&quot;/&gt;</description>
         <guid isPermaLink="false">http://del.icio.us/bws#2008-09-08</guid>
         <pubDate>Tue, 09 Sep 2008 00:00:00 -0700</pubDate>
      </item>
      <item>
         <title>Links for 2008-07-08 [del.icio.us]</title>
         <link>http://feedproxy.google.com/~r/crisisaverted/~3/e3TyU6p0AMs/bws</link>
         <description>&lt;ul&gt;
&lt;li&gt;&lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://www.opera.com/wsc/&quot;&gt;Opera Web Standards Curriculum&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;&lt;img src=&quot;http://feeds.feedburner.com/~r/crisisaverted/~4/e3TyU6p0AMs&quot; height=&quot;1&quot; width=&quot;1&quot;/&gt;</description>
         <guid isPermaLink="false">http://del.icio.us/bws#2008-07-08</guid>
         <pubDate>Wed, 09 Jul 2008 00:00:00 -0700</pubDate>
      </item>
      <item>
         <title>Links for 2008-06-23 [del.icio.us]</title>
         <link>http://feedproxy.google.com/~r/crisisaverted/~3/A_mlXg6sgJg/bws</link>
         <description>&lt;ul&gt;
&lt;li&gt;&lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://billwscott.com/jiffyext/&quot;&gt;Jiffy Firefox Extension&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;&lt;img src=&quot;http://feeds.feedburner.com/~r/crisisaverted/~4/A_mlXg6sgJg&quot; height=&quot;1&quot; width=&quot;1&quot;/&gt;</description>
         <guid isPermaLink="false">http://del.icio.us/bws#2008-06-23</guid>
         <pubDate>Tue, 24 Jun 2008 00:00:00 -0700</pubDate>
      </item>
      <item>
         <title>Links for 2008-06-19 [del.icio.us]</title>
         <link>http://feedproxy.google.com/~r/crisisaverted/~3/WS2dX4dFFcQ/bws</link>
         <description>&lt;ul&gt;
&lt;li&gt;&lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://github.com/protocool/ack-tmbundle/tree/master&quot;&gt;Ack in Project TextMate bundle&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;&lt;img src=&quot;http://feeds.feedburner.com/~r/crisisaverted/~4/WS2dX4dFFcQ&quot; height=&quot;1&quot; width=&quot;1&quot;/&gt;</description>
         <guid isPermaLink="false">http://del.icio.us/bws#2008-06-19</guid>
         <pubDate>Fri, 20 Jun 2008 00:00:00 -0700</pubDate>
      </item>
      <item>
         <title>OR: D.A.R.C. Observatory, 11/21/2009</title>
         <link>http://www.julienlecomte.net/blog/2009/11/395/</link>
         <description>After much consideration, I decided to head to the DARC observatory on Saturday night. It was a little bit of a gamble since the clear sky clock had forecast below average to average transparency, which usually means that wispy clouds would pass overhead, possibly ruining my chances of detecting the most subtle details on the [...]</description>
         <guid isPermaLink="false">http://www.julienlecomte.net/blog/?p=395</guid>
         <pubDate>Sun, 22 Nov 2009 16:49:40 -0800</pubDate>
         <content:encoded><![CDATA[<p>After much consideration, I decided to head to the DARC observatory on Saturday night. It was a little bit of a gamble since the clear sky clock had forecast below average to average transparency, which usually means that wispy clouds would pass overhead, possibly ruining my chances of detecting the most subtle details on the faint targets I was planning to observe. But since it was the last opportunity to go out and observe during this new moon, I took the chance and hoped for the best.</p>
<p>I arrived after dark, around 6pm, and quickly setup my equipment next to Peter Nastcher and his 24&#8243; Starmaster telescope (always a prime spot) Shortly after, a &#8220;show and tell&#8221; presentation took place inside the observatory building. Dr. Bob Caton talked about some of the photographical work he&#8217;s done recently with his 4&#8243; wide field refractor and 20&#8243; Ritchey-Chretien telescope. Daniel Stefanescu talked about M1, and I briefly showed off <a rel="nofollow" target="_blank" href="http://www.julienlecomte.net/blog/2009/11/386/">a few photographs of the early construction of my new 16&#8243; F/4 telescope</a>.</p>
<p>Around 8:50pm, the sky got dark enough to start observing. As expected, thin clouds were passing overhead. Thankfully, they remained to the north, and never really interfered with my plans to observe Herschel II objects in Cetus. By 10pm, the sky was completely clear, and the transparency was actually very decent. The NELM was 6.6 in Aries. After midnight, the air became slightly drier and the transparency slightly better, bumping the NELM to 6.7. The wind was non-existant. The temperature was hovering between the mid and the low 30s. The humidity was high, but the optics remained mostly dew free for the entire night.</p>
<p>Among the highlights of the night, I saw the horse head nebula (Barnard 33) for the first time, using my 12&#8243; telescope and a UHC filter. I was actually surprised by how easy it was to detect. Using a Panoptic 27 without a filter, I was even able to see it along with Alnitak (Zeta Orionis) and the Flame Nebula (NGC 2024) in the same field of view. What an incredible sight! We also looked at the horse head nebula through Peter&#8217;s 24&#8243; scope, and the horse head shape was unmistakable.</p>
<p>The deep red/pink color in M42 was very obvious around the bright blue-green core region and in the two far flung extensions. The E and F stars in the trapezium were easily detected. Finally, Sirius&#8217; companion, affectionately called &#8220;the pup&#8221;, was seen by several observers.</p>
<p>I would like to thank Dr. Lee Hoglan and Dr. Bob Caton for their continued hospitality. It was a good night, and I&#8217;m already looking forward to the next opportunity to observe there. Below is my log for the night. Cheers!</p>
<p>Location: D.A.R.C. Observatory [Elevation 1400ft]<br />
Telescope: Meade Lightbridge 12&#8243; F/5<br />
Eyepieces used:<br />
- Televue Panoptic 27mm (56x – 1.2° TFOV)<br />
- Televue Nagler 16mm type 5 (95x – 52&#8242; TFOV)<br />
- Televue Nagler 9mm type 6 (169x – 29&#8242; TFOV)<br />
- Televue Nagler 7mm type 6 (217x – 22&#8242; TFOV)<br />
- Televue Nagler 5mm type 6 (305x – 16&#8242; TFOV)<br />
(All times are PST)</p>
<p><b>NGC 151</b> GX Cet 00h34m34.6s -09°38&#8242;56&#8243; 12.3 mag 09:05pm<br />
2.5&#8242;x1&#8242; elongated ENE-WSW. Very faint halo. Moderately faint core, round, approximately 30&#8243; in diameter. Stellar nucleus. Moderately bright star just outside the halo at the ENE end.</p>
<p><b>NGC 217</b> GX Cet 00h42m05.7s -09°57&#8242;55&#8243; 13.5 mag 09:20pm<br />
Moderately faint core about 1&#8242;x30&#8243; elongated WNW-ESE. Very faint stellar nucleus. Extremely faint halo roughly 2&#8242; in length elongated WNW-ESE.</p>
<p><b>NGC 337</b> GX Cet 01h00m21.9s -07°31&#8242;21&#8243; 12.0 mag 09:50pm<br />
2&#8242;x1.2&#8242; elongated NW-SE. Moderately faint, very slightly brighter in the center. Subtle hints of mottling detected (?)</p>
<p><b>NGC 357</b> GX Cet 01h03m53.7s -06°17&#8242;02&#8243; 13.2 mag 10:05pm<br />
Round, 20&#8243; in diameter. Hints of a stellar nucleus (?) Only the core was positevely detected. The halo must be extremely faint! Moderately faint star about 40&#8243; E.</p>
<p><b>NGC 636</b> GX Cet 01h39m38.2s -07°27&#8242;37&#8243; 12.4 mag 10:15pm<br />
Fairly bright core, round, 20&#8243; in diameter, fairly bright stellar nucleus, very faint halo, gradually dimmer toward the outside. Did not note the extent and position angle of the halo.</p>
<p><b>NGC 428</b> GX Cet 01h13m28.0s +01°02&#8242;13&#8243; 11.9 mag 10:45pm<br />
3&#8242;x2&#8242; elongated NW-SE, moderately faint. Very slightly brighter core, round, 45&#8243; in diameter. Two bright stars (mag 8.6 and 8.7) about 8&#8242; W and 8&#8242; NNE. Interestingly enough, I did not note the presence of two prominent albeit dimmer stars (mag 11.9 and 12.5) located just outside the halo to the S and the NW.</p>
<p><b>NGC 1045</b> GX Cet 02h41m00.0s -11°14&#8242;01&#8243; 13.5 mag 10:55pm<br />
Fairly faint, round, 30&#8243; in diameter. Moderately faint stellar nucleus.</p>
<p><b>NGC 991</b> GX Cet 02h36m04.2s -07°06&#8242;32&#8243; 12.9 mag 11:30pm<br />
Very faint uniform glow about 1.5&#8242; in diameter, very slightly brighter core. Moderately bright star (mag 13.4) about 1.5&#8242; S.</p>
<p><b>NGC 1035</b> GX Cet 02h40m00.6s -08°05&#8242;23&#8243; 12.9 mag 11:45pm<br />
2&#8242;x30&#8243; elongated NNW-SSE, moderately faint, fairly uniform. Moderately faint star at the SSE tip.</p>
<p><b>NGC 1087</b> GX Cet 02h46m57.7s -00°27&#8242;17&#8243; 11.5 mag 12:05am<br />
2&#8242;x1&#8242; elongated N-S. Moderately bright, pretty uniform, very slightly brighter core.</p>
<p><b>NGC 1090</b> GX Cet 02h47m06.5s -00°12&#8242;11&#8243; 12.6 mag 12:10am<br />
2&#8242;x1&#8242; elongated E-W, fairly faint, pretty uniform. Slightly brighter core about 20&#8243; in diameter. Pretty faint star (mag 15.2) just 45&#8243; S.</p>
<p><b>NGC 1032</b> GX Cet 02h39m56.4s +01°08&#8242;21&#8243; 12.6 mag 12:30am<br />
2&#8242;x45&#8243; elongated ENE-WSW. Moderately faint core, about 30&#8243; in diameter, slightly elongated ENE-WSW. Three moderately bright stars (mag 13.2, 13.2 and 13.5) to the E, NE and N, about 1.5&#8242; from the core.</p>
<p><b>NGC 1070</b> GX Cet 02h43m55.6s +05°00&#8242;47&#8243; 12.6 mag 12:40am<br />
Moderately faint core, about 30&#8243; in diameter, very slightly elongated N-S. Very faint halo, about 1.5&#8242; in diameter.</p>
<p><b>NGC 1073</b> GX Cet 02h44m13.0s +01°25&#8242;13&#8243; 11.6 mag 01:05am<br />
Round, uniform, faint glow, about 4&#8242; in diameter. Extremely slightly brighter core. A DSS image shows that this galaxy is a barred spiral. I did not see any visual evidence of that.</p>
<p><b>NGC 1514</b> (Crystal Ball Nebula) PN Tau 04h09m57.0s +30°48&#8242;15&#8243; 10.8 mag 01:30am<br />
Moderately faint, roundish nebulosity, about 2&#8242; in diameter, very slightly elongated NNW-SSE, surrounding a bright star (mag 9.4). Appears uniform at first. A UHC filter reveals irregularities in brightness. The nebulosity appears slightly dimmer around the central star, although this may be a visual artifact due to the presence of the bright central star (a DSS image shows that it is indeed a real feature). Hints of mottling. Brighter knots to the SSE and NNW.</p>
<p><b>NGC 1762</b> GX Ori 05h04m10.0s +01°35&#8242;21&#8243; 13.4 mag 01:40am<br />
Very faint glow, less than 1&#8242; in diameter, possibly slightly elongated N-S. Moderately faint superimposed star just 15&#8243; E.</p>
<p><b>NGC 1587</b> GX Tau 04h31m12.8s +00°41&#8242;09&#8243; 12.7 mag 01:50am<br />
Round, about 45&#8243; in diameter, moderately faint, gradually brighter toward the center. Forms a nice tight pair with NGC 1588, located just 1&#8242; E.</p>]]></content:encoded>
         <category>Astronomy</category>
      </item>
      <item>
         <title>From Dream To Reality</title>
         <link>http://www.julienlecomte.net/blog/2009/11/386/</link>
         <description>I have always been a pragmatic person. While designing my telescope using computer assisted design software was a very rewarding experience, I have felt a much greater sense of accomplishment making it happen. This is why I am very proud to show off the mirror box of my future telescope. This is the result of [...]</description>
         <guid isPermaLink="false">http://www.julienlecomte.net/blog/?p=386</guid>
         <pubDate>Sat, 21 Nov 2009 10:40:10 -0800</pubDate>
         <content:encoded><![CDATA[<p><img style="width:125px;height:113px;float:left;margin-right:10px;"></p>
<p>I have always been a pragmatic person. While designing my telescope using computer assisted design software was a very rewarding experience, I have felt a much greater sense of accomplishment making it happen. This is why I am very proud to show off the mirror box of my future telescope. This is the result of 4 nights of work at <a rel="nofollow" target="_blank" href="http://www.sawdustshop.com/">the sawdust shop</a> in Sunnyvale. I am very happy with the way it turned out, and look forward to getting more work done in the next few weeks! <strong>Note:</strong> click on the thumbnails below to see the full size photographs.</p>
<p><br style="clear:both;line-height:0;"/></p>
<p><a rel="nofollow" style="float:left;margin-right:10px;"><img style="width:180px;height:135px;"></a></p>
<p><a rel="nofollow" style="float:left;margin-right:10px;"><img style="width:180px;height:135px;"></a></p>
<p><a rel="nofollow" style="float:left;margin-right:10px;"><img style="width:180px;height:135px;"></a></p>
<p><br style="clear:both;line-height:0;"/></p>
<p><a rel="nofollow" style="float:left;margin-right:10px;"><img style="width:180px;height:135px;"></a></p>
<p><a rel="nofollow" style="float:left;margin-right:10px;"><img style="width:180px;height:135px;"></a></p>
<p><a rel="nofollow" style="float:left;margin-right:10px;"><img style="width:180px;height:135px;"></a></p>
<p><br style="clear:both;line-height:0;"/></p>]]></content:encoded>
         <category>Astronomy</category>
      </item>
      <item>
         <title>OR: Dinosaur Point, 11/14/09</title>
         <link>http://www.julienlecomte.net/blog/2009/11/379/</link>
         <description>After a short (55 minutes) and pleasant drive, I arrived at Dinosaur Point early (around 4pm) because of the new access rules, and to have plenty of time to setup my equipment. Albert Highe, George Feliz and Peter Natscher arrived shortly after and setup right next to me. Dave Cooper, Jamie Dillon, Bob Jardine and [...]</description>
         <guid isPermaLink="false">http://www.julienlecomte.net/blog/?p=379</guid>
         <pubDate>Sun, 15 Nov 2009 19:49:45 -0800</pubDate>
         <content:encoded><![CDATA[<p>After a short (55 minutes) and pleasant drive, I arrived at Dinosaur Point early (around 4pm) because of the new access rules, and to have plenty of time to setup my equipment. Albert Highe, George Feliz and Peter Natscher arrived shortly after and setup right next to me. Dave Cooper, Jamie Dillon, Bob Jardine and Al Howard were a little further down the parking lot. What a great team of observers! (ok, Al doesn&#8217;t really count as an observer, but he&#8217;s cool nonetheless)</p>
<p>The wind was non-existant. The temperature dropped from the low 60s to the mid to low 40s, which is not a huge difference. This always helps with the seeing, especially in large newtonians. The transparency was about average until about 9pm, when it got slightly better. At 9:30pm, I did a NELM test in Triangulum and obtained 6.3, which is pretty good for the site.</p>
<p>Since I don&#8217;t have a whole lot of Herschel 400 targets left around this time of the year, I decided to observe mostly Herschel II objects, and finished the night with a couple of galaxy groups from Alvin Huey&#8217;s &#8220;Selected small galaxy groups&#8221; observing guide. Among the highlights of the night, we observed NGC 891 and M 33 through Peter&#8217;s 24&#8243; Starmaster telescope. The views were absolutely breathtaking! We also looked at the hydrogen filaments inside M 1, which we also detected through George&#8217;s 13&#8243; scope, and to a lesser extent in my own 12&#8243; scope.</p>
<p>Overall, I was very pleased with the evening, and it reminded me of why I like Dinosaur Point so much: short easy drive, fairly good skies, setup on a paved parking lot, in bed by 2am after 6+ hours of observing! Below is my log for the night. Cheers!</p>
<p>Location: Dinosaur Point [Elevation 648 ft]<br />
Telescope: Meade Lightbridge 12&#8243; F/5<br />
Eyepieces used:<br />
- Televue Panoptic 27mm (56x – 1.2° TFOV)<br />
- Televue Nagler 16mm type 5 (95x – 52&#8242; TFOV)<br />
- Televue Nagler 9mm type 6 (169x – 29&#8242; TFOV)<br />
- Televue Nagler 7mm type 6 (217x – 22&#8242; TFOV)<br />
- Televue Nagler 5mm type 6 (305x – 16&#8242; TFOV)<br />
(All times are PST)</p>
<p><b>NGC 7184</b> GX Aqr 22h03m13.7s -20°45&#8242;54&#8243; 11.7 mag 06:20pm<br />
Moderately faint slightly elongated core, stellar nucleus, very faint halo elongated 3&#215;1 ENE-WSW. Very faint superimposed star about 1&#8242; ENE of nucleus. Fairly bright star at the ENE end of the halo.</p>
<p><b>NGC 7218</b> GX Aqr 22h10m45.0s -16°36&#8242;39&#8243; 12.4 mag 06:40pm<br />
2&#8242;x1&#8242; elongated NNE-SSW. Gradually brighter toward a moderately faint core. Moderately bright superimposed stars 1&#8242; E and 1&#8242; NNE. Best seen at 217x.</p>
<p><b>NGC 7171</b> GX Aqr 22h01m35.0s -13°13&#8242;17&#8243; 13.1 mag 06:50pm<br />
Moderately large, very low surface brightness, only very slightly brighter in the core. Elongated 3:2 NW-SE. Extremely faint superimposed star 1&#8242; E.</p>
<p><b>NGC 7377</b> GX Aqr 22h48m20.9s -22°15&#8242;31&#8243; 12.1 mag 07:10pm<br />
Small (about 1&#8242; in diameter), round and fairly bright. Stellar nucleus. A small grouping of 5 fairly bright stars is located just SW of this galaxy.</p>
<p><b>NGC 7392</b> GX Aqr 22h52m21.9s -20°33&#8242;18&#8243; 12.6 mag 07:20pm<br />
2&#8242;x1&#8242; elongated WNW-ESE. Stellar nucleus embedded inside a fairly bright small core.</p>
<p><b>NGC 7600</b> GX Aqr 23h19m26.0s -07°31&#8242;25&#8243; 12.9 mag 07:35pm<br />
1.5&#8242;x1&#8242; elongated ENE-WSW. Moderately faint stellar nucleus.</p>
<p><b>NGC 7156</b> GX Peg 21h55m04.6s +02°59&#8242;32&#8243; 13.3 mag 08:00pm<br />
Small (about 1&#8242; in diameter), round, dim, fairly uniform, only slightly brighter core.</p>
<p><b>NGC 7177</b> GX Peg 22h01m10.3s +17°47&#8242;23&#8243; 11.9 mag 08:10pm<br />
Round bright core, about 1&#8242; in diameter, surrounded by a faint halo 2.5&#8242;x1.5&#8242; elongated E-W. Stellar nucleus. Best seen at 217x.</p>
<p><b>NGC 7332</b> GX Peg 22h37m54.1s +23°51&#8242;14&#8243; 12.0 mag 08:25pm<br />
Very bright stellar nucleus embedded inside a bright compact core. Moderately faint halo roughly 2.5&#8242;x45&#8243; elongated NNW-SSE. Forms a beautiful pair with NGC 7339 at 217x.</p>
<p><b>NGC 7742</b> GX Peg 23h44m47.4s +10°49&#8242;32&#8243; 12.3 mag 08:50pm<br />
Small (about 1&#8242; in diameter), round, fairly bright, gradually brighter to a stellar nucleus. Mag 12.7 star just 1.5&#8242; ESE.</p>
<p><b>NGC 23</b> GX Peg 00h10m25.7s +25°59&#8242;00&#8243; 12.8 mag 09:05pm<br />
Small (&lt; 1') round faint halo, fairly bright almost stellar core. A fairly bright star is at the SSW end. Forms a nice pair with dimmer NGC 26.</p>
<p><b>NGC 604</b> BN Tri 01h35m11.7s +30°50&#8242;17&#8243; mag 09:25pm<br />
This nebula physically belongs to M33. Seen easily in a 12&#8243; scope as a bright round patch about 1&#8242; in size. In Peter Natscher&#8217;s 24&#8243; scope, its shape appears slightly irregular.</p>
<p><b>NGC 598</b> (M 33) GX Tri 01h34m26.5s +30°42&#8242;53&#8243; 6.4 mag 09:25pm<br />
Barely detected naked eye. Easily seen in 9&#215;50 finder scope, including the broad S-shaped spiral structure. Elongated 3:2 NNE-SSW. Large bright round core. Appears amazing in a 12&#8243; scope, with lots of fine details easily visible in the spiral arms. Absolutely dazzling though Peter Natscher&#8217;s 24&#8243; scope! Several NGC objects physically belong to M33: NGC 604, NGC 595, NGC 592 and NGC 588. All were seen very easily in a 12&#8243; scope.</p>
<p><b>NGC 7640</b> GX And 23h22m36.4s +40°54&#8242;19&#8243; 11.6 mag 09:40pm<br />
6&#8242;x1.5&#8242; elongated NNW-SSE. Moderately faint halo with a slightly brighter core. Slight impression of mottling. Fairly bright superimposed star just SE of the core. 2 superimposed stars in the halo N of the core.</p>
<p><b>NGC 206</b> BN And 00h41m04.3s +40°47&#8242;34&#8243; mag 09:45pm<br />
Star cloud that physically belongs to M31. Located about 40&#8242; SW of M31&#8217;s core. Roughly 5&#8242;x2&#8242; elongated N-S. Fairly faint.</p>
<p><b>NGC 214</b> GX And 00h42m01.3s +25°33&#8242;29&#8243; 12.9 mag 10:00pm<br />
Fairly small (1.5&#8242;x1&#8242;), elongated ENE-WSW, moderately faint, pretty uniform, slightly brighter core. Barely detected stellar nucleus.</p>
<p><b>NGC 1068</b> (M 77) GX Cet 02h43m13.3s +00°01&#8242;54&#8243; 9.7 mag 10:20pm<br />
Roughly circular, moderately faint halo, about 2&#8242; in diameter, very slightly elongated N-S. Bright slightly S-shaped core elongated 3:2 NE-SW containing a very bright stellar nucleus. Some mottling visible (hints of broader spiral arms emanating from the core)</p>
<p><b>NGC 672</b> GX Tri 01h48m30.0s +27°29&#8242;11&#8243; 11.4 mag 10:50pm<br />
5&#8242;x2&#8242; elongated ENE-WSW, pretty uniform, moderately bright. Forms a nice pair with much dimmer galaxy IC 1727 located about 8&#8242; SW.</p>
<p><b>NGC 925</b> GX Tri 02h27m54.9s +33°37&#8242;36&#8243; 10.6 mag 11:10pm<br />
4&#8242;x2&#8242; elongated WNW-ESE. Moderately faint, pretty uniform, slightly brighter core. Many fairly bright field stars enhance the view.</p>
<p><b>NGC 890</b> GX Tri 02h22m38.8s +33°18&#8242;53&#8243; 12.8 mag 11:15pm<br />
Small (about 1.5&#8242;x45&#8243;) elongated NE-SW. Fairly bright, gradually brighter to an almost stellar nucleus.</p>
<p><b>NGC 68 group</b><br />
Pretty compact. A few field stars distract the observer, making the 3 galaxies in the center harder to spot.<br />
NGC 68<br />
NGC 69 (very faint)<br />
NGC 70<br />
NGC 71<br />
NGC 72<br />
NGC 72A (very faint)<br />
NGC 74 (very faint)</p>
<p><b>NGC 383 group</b><br />
Fairly bright members, loose group.<br />
NGC 373 (faint)<br />
NGC 375 (faint)<br />
NGC 379<br />
NGC 380<br />
NGC 382<br />
NGC 383<br />
NGC 384<br />
NGC 385<br />
NGC 386 (faint)<br />
NGC 387 (very faint)<br />
NGC 388</p>]]></content:encoded>
         <category>Astronomy</category>
      </item>
      <item>
         <title>Entering the World of Amateur Telescope Making</title>
         <link>http://www.julienlecomte.net/blog/2009/11/365/</link>
         <description>For the past few weeks, I&amp;#8217;ve been designing my next telescope, an Albert Highe inspired 16&amp;#8243; dobsonian. The decision to build my own telescope stemmed from the fact that I knew exactly what I wanted, and I could not get it from any of the well known US telescope manufacturers. In addition, I wanted to [...]</description>
         <guid isPermaLink="false">http://www.julienlecomte.net/blog/?p=365</guid>
         <pubDate>Sat, 07 Nov 2009 11:05:45 -0800</pubDate>
         <content:encoded><![CDATA[<p><a rel="nofollow"><img style="width:100px;height:120px;float:left;margin-right:10px;"></a></p>
<p>For the past few weeks, I&#8217;ve been designing my next telescope, an Albert Highe inspired 16&#8243; dobsonian. The decision to build my own telescope stemmed from the fact that I knew exactly what I wanted, and I could not get it from any of the well known US telescope manufacturers. In addition, I wanted to learn new skills, including computer assisted design and woodworking. The image to the left is the latest rendering of the optical tube assembly as I envisioned it (click for a higher resolution image). Below are my original specifications:</p>
<p><br style="clear:both;line-height:0;"/></p>
<ul>
<li>The mirror box and rocker box must fit together within 24&#8243; x 24&#8243; x 18&#8243;, so that it fits in my car.</li>
<li>The eyepiece height cannot exceed 64&#8243;, so that I don&#8217;t have to use a step stool or a ladder.</li>
<li>The weight of the heaviest component cannot exceed 40 lbs, so that I can easily lift it.</li>
<li>Overall cost must not exceed $5,000.</li>
</ul>
<p>I opted for a 16&#8243; F/4 mirror, which should fit my goals. In the next few months, I will be posting photographs as I build and assemble the various parts that make up the telescope. Stay tuned!</p>]]></content:encoded>
         <category>Astronomy</category>
      </item>
      <item>
         <title>OR: Deep Sky Ranch, 10/16/09: Tarentulas and Galaxy Clusters</title>
         <link>http://www.julienlecomte.net/blog/2009/10/332/</link>
         <description>I had originally planned to go to the DARC observatory on Saturday night. However, due to a dismal weather forecast, I was forced to rethink my plans. The forecast for Friday night was actually looking pretty good, and an opportunity came up to go to Willow Springs. I had never been up there before, so [...]</description>
         <guid isPermaLink="false">http://www.julienlecomte.net/blog/?p=332</guid>
         <pubDate>Sat, 17 Oct 2009 15:44:08 -0700</pubDate>
         <content:encoded><![CDATA[<p>I had originally planned to go to the DARC observatory on Saturday night. However, due to a dismal weather forecast, I was forced to rethink my plans. The forecast for Friday night was actually looking pretty good, and an opportunity came up to go to Willow Springs. I had never been up there before, so I jumped at the opportunity, packed my gear in a hurry, and headed down to Deep Sky Ranch.</p>
<p>While driving on Little Panoche Rd, something interesting caught my eye: a tarantula was slowly crossing the roadway. On the way back this morning, I pulled over to take this photograph:</p>
<p><img width="483" height="319"></p>
<p>Willow Springs is a great place for deep sky visual observing. The sky is fairly dark, and the only really noticeable light dome, emanating from Hollister, is not much of a problem. Here is a summary of last night&#8217;s weather conditions:</p>
<ul>
<li>No wind.</li>
<li>Temperatures in the low 50s.</li>
<li>Average seeing.</li>
<li>Average transparency.</li>
<li>Very high humidity: my table top and paper charts were soaked, and my eyepieces were covered in dew.</li>
</ul>
<p>Were present Steve Gottlieb, Mark Wagner, Mark Johnston, Rogelio Bernal Andreo, Richard Navarette and of course our gracious host, Kevin Ritschel. Here is a photo of famous DobZilla, Kevin&#8217;s 30&#8243; dobsonian telescope:</p>
<p><img width="400" height="300"></p>
<p>Since I am almost done with the Herschel 400 list, I had decided to start a new project: observing the galaxy groups featured in one of <a rel="nofollow" target="_blank" href="http://www.faintfuzzies.com/ObservingGuidebooks.htm">Alvin Huey&#8217;s free downloadable observing guides</a>: Selected Small Galaxy Groups. These galaxy groups are fascinating because they are a real test of the observer&#8217;s visual acuity and equipment. Although the brightest members are usually immediately detected, these groups reward patient observers. The more time is spent at the eyepiece, the greater the number of galaxies that become visible! This way, I was able to detect a good number of members after spending about 30 minutes on a given group. I did not take detailed notes of my observations this time around, but I did write down the list of members I was positively able to detect. All observations were done using my Meade Lightbridge 12&#8243; F/5 dobsonian telescope, and using mostly my 9mm Televue Nagler type 6.</p>
<p>NGC 383 Group (also known as the Pisces Group)<br />
NGC 373/NGC 375/NGC 379/NGC 380/NGC 382/NGC 383/NGC 384/NGC 385/NGC 386/NGC 387 (hard!)/NGC 388</p>
<p>NGC 3 Group (Pisces)<br />
NGC 3/NGC 4 (hard!)/NGC 7837/NGC 7838</p>
<p>NGC 507 Group (Pisces)<br />
NGC 494/NGC 495/NGC 496/NGC 499/NGC 501/NGC 503/NGC 504/NGC 507/NGC 508/NGC 515/NGC 517/IC 1682/IC 1687/IC 1689/IC 1690</p>
<p>NGC 80 Group (Andromeda) &#8211; Featured in the current edition of S&#038;T&#8217;s &#8220;Going Deep&#8221; column.<br />
NGC 79/NGC 80/NGC 81 (hard!)/NGC 83/MGC 4-2-10 (PGC 1384, and also sometimes incorrectly labeled NGC 84) (hard!)/NGC 85/NGC 86/NGC 90/NGC 93/NGC 94/NGC 96<br />
I also observed this group through Mark Johnston 18&#8243; scope, and confirmed seeing some of the dimmest members.</p>
<p>Perseus Cluster<br />
NGC 1129/NGC 1130/NGC 1131/IC 265/MCG 7-7-3 (PGC 10953)/MCG 7-7-8 (PGC 10980)</p>
<p>Big thanks to Kevin Ritschel for hosting this star party and for sharing stunning views through DobZilla. Also, big thanks to Alvin Huey for putting together the observing guides and making them freely downloadable on his web site.</p>]]></content:encoded>
         <category>Astronomy</category>
      </item>
      <item>
         <title>OR: Henry Coe State Park, 10/10/09</title>
         <link>http://www.julienlecomte.net/blog/2009/10/328/</link>
         <description>Mark Johnston, Peter Krottje and I met at the overflow parking lot at Henry Coe state park last night. I brought my Meade Lightbridge 12&amp;#8243; (after flocking the inside of the UTA with black velvet ordered from Edmund Optics), while Mark brought both his 18&amp;#8243; Starmaster dobsonian as well as a newly acquired equatorially mounted [...]</description>
         <guid isPermaLink="false">http://www.julienlecomte.net/blog/?p=328</guid>
         <pubDate>Sun, 11 Oct 2009 20:04:30 -0700</pubDate>
         <content:encoded><![CDATA[<p>Mark Johnston, Peter Krottje and I met at the overflow parking lot at Henry Coe state park last night. I brought my Meade Lightbridge 12&#8243; (after flocking the inside of the UTA with black velvet ordered from Edmund Optics), while Mark brought both his 18&#8243; Starmaster dobsonian as well as a newly acquired equatorially mounted 190mm Orion Mak-Newt. Peter was using his homemade 10&#8243; ultra light dobsonian.</p>
<p>The sky grew darker as the evening went on thanks to the fog dimming the lights emanating from San Jose, Morgan Hill and Gilroy. By 11pm, we were getting SQM readings of almost 21.2, which is pretty good for Henry Coe. The transparency however was clearly below average, and the low level haze was causing some obvious dimming up to 15 degrees of elevation, especially to the south and the west. The sky was however more than decent between the north east and the south east, which is where I spent most of the night, observing mostly open clusters in Andromeda, Lacerta and Cassiopeia.</p>
<p>Here&#8217;s a summary of the weather conditions:</p>
<ul>
<li>Average seeing.</li>
<li>Mild (but annoying) westerly wind.</li>
<li>Surprisingly cold (I had to really bundle up, and almost needed gloves by 11pm)</li>
</ul>
<p>Here are some of the highlights of the evening:</p>
<ul>
<li>18 open clusters from the Herschel 400 list. Most of them were honestly not very interesting, except maybe the ET cluster, and a couple of clusters in Cassiopeia that happened to fit within the same FOV of my Pan 27, showing some differences in structure.</li>
<li>We observed the California nebula with my 50mm finder scope using a 16mm Nagler type 5 and a UHC filter. We got a much better view through Mark&#8217;s 190mm Orion Mak-Newt using a wide field eyepiece and an H-beta filter.</li>
<li>We saw the fourth flea around NGC 7331 through Mark&#8217;s 18&#8243; scope, and I later caught a glimpse of it in my 12&#8243; scope, although it was coming in and out of view (knowing where to look really helps!)</li>
<li>The GRS was transiting. A darker slightly elongated region was spotted right next to it. Probably some disturbance in the equatorial band.</li>
<li>There was a nice shadow transit by Io on Jupiter.</li>
</ul>
<p>It was my first night using the Orion self-centering adapter (instead of a standard 1 1/4&#8243; adapter with a tightening ring) and I have to say that I really liked it! I&#8217;m sure it will be very handy this winter when switching eyepieces while wearing gloves.</p>
<p>I took off around midnight, and was soundly asleep by 1am. Overall, it was a good night, and I&#8217;m glad I went out. I&#8217;m looking forward to observing under darker skies next weekend to start on the Herschel II list, since I&#8217;m running out of Herschel I objects. Below is my log for the night. Cheers!</p>
<p>Location: Henry Coe state park [Elevation 2600 ft]<br />
Telescope: Meade Lightbridge 12&#8243; F/5<br />
Eyepieces used:<br />
- Televue Panoptic 27mm (56x – 1.2° TFOV)<br />
- Televue Nagler 16mm type 5 (95x – 52&#8242; TFOV)<br />
- Televue Nagler 9mm type 6 (169x – 29&#8242; TFOV)<br />
- Televue Nagler 7mm type 6 (217x – 22&#8242; TFOV)<br />
- Televue Nagler 5mm type 6 (305x – 16&#8242; TFOV)<br />
(All times are PDT)</p>
<p><b>NGC 7296</b> OC Lac 22h28m27.3s +52°22&#8242;19&#8243; 9.7 mag 08:00pm<br />
About 30 stars, a dozen of which are fairly bright, grouped within an area roughly 4&#8242; in diameter. Relatively inconspicuous, best seen at 217x.</p>
<p><b>NGC 7243</b> OC Lac 22h15m32.9s +49°57&#8242;09&#8243; 6.7 mag 08:05pm<br />
About 80 stars, 20 of which are pretty bright, within an area 25&#8242; x 15&#8242; elongated NE-SW. The center region, delimited to the west by a nice double star, is very sparsely populated.</p>
<p><b>NGC 7209</b> OC Lac 22h05m32.1s +46°32&#8242;11&#8243; 7.8 mag 08:10pm<br />
About 80 stars, 40 of which are uniformly pretty bright, within an area 20&#8242; x 15&#8242; elongated NNE-SSW. Moderately bright and slightly orange star near the center. Bright yellow star (HT Lac, mag 6.2) about 15&#8242; N.</p>
<p><b>NGC 7686</b> OC And 23h30m37.3s +49°11&#8242;31&#8243; 5.6 mag 08:15pm<br />
About 30 moderately faint to moderately bright stars grouped within an area 15&#8242; in diameter centered on a bright yellow-orange star (HD 221246, mag 6.2)</p>
<p><b>NGC 7789</b> OC Cas 23h57m56.4s +56°46&#8242;02&#8243; 7.5 mag 08:50pm<br />
Very rich and fairly compact. Very large number of moderately faint stars of comparable brightness scattered pretty uniformly within a roughly circular area 15&#8242; in diameter.</p>
<p><b>NGC 7790</b> OC Cas 23h58m56.7s +61°16&#8242;01&#8243; 7.2 mag 09:00pm<br />
About 20 moderately faint stars within an area roughly 5&#8242; x 3&#8242; elongated E-W. The proximity of numerous star clusters in the vicinity (esp. NGC 7788) makes this cluster interesting to track down.</p>
<p><b>NGC 129</b> OC Cas 00h30m36.0s +60°16&#8242;34&#8243; 9.8 mag 09:10pm<br />
Located 15&#8242; NNW of a bright star (HD 2626, mag 5.9) This cluster contains a good number of moderately bright to fairly bright stars. It is not very well delimited, especially to the north, making star counts unreliable. A few fairly bright stars form a ring elongated 3:2 NW-SE.</p>
<p><b>NGC 136</b> OC Cas 00h32m07.4s +61°34&#8242;04&#8243; mag 09:20pm<br />
Maybe a dozen faint stars grouped within an area 1.5&#8242; in diameter. About 6&#8242; NE of a fairly bright yellowish star (SAO 11238, mag 8.4) This cluster is so inconspicuous that a good atlas is a must to confirm that you&#8217;re indeed looking at the right spot.</p>
<p><b>NGC 381</b> OC Cas 01h08m59.4s +61°38&#8242;19&#8243; 9.3 mag 09:30pm<br />
Fairly sparse cluster containing about 30 moderately faint to moderately bright stars within an area roughly 6&#8242; in diameter. Best seen at 169x.</p>
<p><b>NGC 225</b> (Sailboat Cluster) OC Cas 00h44m16.8s +61°49&#8242;55&#8243; 8.9 mag 09:35pm<br />
About 30 bright stars within an area 12&#8242; x 8&#8242; elongated NE-SW. Requires some imagination to see the outline of a sailboat&#8230;</p>
<p><b>NGC 457</b> (ET Cluster) OC Cas 01h20m15.4s +58°20&#8242;27&#8243; 5.1 mag 09:40pm<br />
Two bright stars (mag 5 and 7, the one to the NE being the brighter), located at the western end of the cluster, about 3&#8242; apart, form the eyes of the ET cluster. A narrow group of stars, elongated NW-SE, form the body, and a few more bright stars form the arms.</p>
<p><b>NGC 559</b> OC Cas 01h30m14.5s +63°21&#8242;35&#8243; 7.4 mag 10:25pm<br />
About 30 fairly faint stars within an area roughly 5&#8242; in diameter. Best seen at 169x.</p>
<p><b>NGC 436</b> OC Cas 01h16m38.2s +58°51&#8242;58&#8243; 9.3 mag 10:25pm<br />
Fairly compact cluster containing about 25 moderately bright to moderately faint stars within an area 5&#8242; in diameter. Best seen at 169x.</p>
<p><b>NGC 637</b> OC Cas 01h43m49.4s +64°05&#8242;29&#8243; 7.3 mag 10:35pm<br />
Small, compact group of about 20 stars, 5 of which are fairly bright, the others are fairly faint, within an area roughly 3&#8242; in diameter elongated NE-SW. Best seen at 217x.</p>
<p><b>NGC 654</b> OC Cas 01h44m44.2s +61°56&#8242;11&#8243; 8.2 mag 10:40pm<br />
About 40 moderately faint stars within 5&#8242;. Best seen at 169x. Located 3&#8242; NNW of a bright yellow-orange star (HD 10494, mag 7.3) Fits with NGC 663 in the same field of view of my Panoptic 27mm eyepiece, showing some nice difference in structure.</p>
<p><b>NGC 663</b> OC Cas 01h46m53.1s +61°17&#8242;10&#8243; 6.4 mag 10:40pm<br />
About 80 fairly bright stars within an area 15&#8242; x 10&#8242; elongated NW-SE. Fits with NGC 654 in the same field of view of my Panoptic 27mm eyepiece, showing some nice difference in structure.</p>
<p><b>NGC 659</b> OC Cas 01h45m07.6s +60°43&#8242;29&#8243; 7.2 mag 10:45pm<br />
About 15 moderately faint stars within an area 4&#8242; in diameter. Best seen at 169x. Located about 15&#8242; NE of a trio of bright stars.</p>
<p><b>NGC 752</b> OC And 01h58m18.5s +37°50&#8242;08&#8243; 6.6 mag 10:50pm<br />
Seen with the naked eye as a fuzzy spot between Tri and And. Best seen using the 50mm finder scope using a 16mm Nagler type 5 eyepiece. In my 12&#8243; scope, using a Panoptic 27mm eyepiece, more than 100 bright stars are visible. Two bright yellowish stars were seen near the south-western boundary (56 And and HD 11727, mag 5.7 and 5.9 respectively)</p>]]></content:encoded>
         <category>Astronomy</category>
      </item>
      <item>
         <title>CalStar 2009</title>
         <link>http://www.julienlecomte.net/blog/2009/09/323/</link>
         <description>I was only able to attend the first two nights of CalStar, an annual Star Party that takes place at Lake San Antonio in California. The first night (Thu, Sep 17), the transparency was mediocre (when I called it a night, around 2am, Jupiter was surrounded by a bright halo&amp;#8230;). Therefore, I used that first [...]</description>
         <guid isPermaLink="false">http://www.julienlecomte.net/blog/?p=323</guid>
         <pubDate>Fri, 25 Sep 2009 11:58:23 -0700</pubDate>
         <content:encoded><![CDATA[<p>I was only able to attend the first two nights of <a rel="nofollow" target="_blank" href="http://www.observers.org/CalStar/">CalStar</a>, an annual Star Party that takes place at Lake San Antonio in California. The first night (Thu, Sep 17), the transparency was mediocre (when I called it a night, around 2am, Jupiter was surrounded by a bright halo&#8230;). Therefore, I used that first night to focus on bright easy objects. The second night (Fri, Sep 18) was much better with an NELM of 6.7 in UMi. Seeing on both nights was about average. However, the high temperatures during the day caused my (thick) mirror to take many hours to cool down, even with the fan on (and I made the mistake of keeping the shroud on&#8230;)</p>
<p>Among the highlights, I was able to see Uranus (easy) and M 33 (hard) naked eye, as well as catch the two brightest satellites of Uranus with my scope. Dave Cooper and Peter Natscher also shared some superb views in their scopes (respectively an AP 6&#8243; apo refractor and a 24&#8243; F/3.7 Starmaster dobsonian telescope)</p>
<p>I thoroughly enjoyed the conversations I had during the day with fellow observers. That&#8217;s why I&#8217;ve come to love star parties. Even if the weather is not so great, it&#8217;s always a fantastic opportunity to learn new things.</p>
<p>Below is my log for both nights. Most objects are from the Herschel 400 list. From now on, I will start mixing in Herschel II and Herschel I objects in my observing routine, in addition to some objects from Alvin Huey&#8217;s awesome free guides: &#8220;Selected Small Galaxy Groups&#8221; and &#8220;Selected Galaxy Trios&#8221; (which I had printed and coil binded at Fedex Kinko&#8217;s) Cheers!</p>
<p>Location: Lake San Antonio [Elevation 1082 ft]<br />
Telescope: Meade Lightbridge 12&#8243; F/5<br />
Eyepieces used:<br />
- Televue Panoptic 27mm (56x – 1.2° TFOV)<br />
- Televue Nagler 16mm type 5 (95x – 52&#8242; TFOV)<br />
- Televue Nagler 9mm type 6 (169x – 29&#8242; TFOV)<br />
- Televue Nagler 7mm type 6 (217x – 22&#8242; TFOV)<br />
- Televue Nagler 5mm type 6 (305x – 16&#8242; TFOV)<br />
(All times are PDT)</p>
<h3>Thursday, September 17, 2009</h3>
<p><b>NGC 7142</b> OC Cep 21h45m25.3s +65°49&#8242;26&#8243; 10.0 mag 08:40pm<br />
Very inconspicuous group of about 40 moderately faint stars over a milky background. Slightly elongated WNW-ESE. A few brighter stars delimit this cluster on the north and east sides.</p>
<p><b>NGC 7331</b> GX Peg 22h37m33.1s +34°28&#8242;14&#8243; 10.2 mag 09:00pm<br />
Elongated 3&#215;1 NNW-SSE. Fairly bright core region surrounding a bright stellar nucleus visible at 217x and 305x during brief moments of better seeing. The halo is rather dim compared to the core. It extends about 6&#8242; along its major axis. The western half of the galaxy looks darker, due to the presence of a dark lane. Very faint superimposed star about 2&#8242; SSE of nucleus. NGC 7335, NGC 7337 and NGC 7340 were easily detected. NGC 7336 was not detected. I did not search for nearby NGC 7325 and NGC 7326.</p>
<p><b>NGC 6210</b> (Turtle Nebula) PN Her 16h44m54.4s +23°47&#8242;05&#8243; 9.7 mag 09:25pm<br />
At 95x, this planetary nebula appears bright, almost stellar, and exhibits an obvious blue color. At 217x and 305x, the color is a bit washed out. At those magnifications, this planetary nebula appears round and very uniform, about 10 to 15&#8243; in diameter, and seems to be surrounded by a slightly larger and rather faint envelope (unless this is scattered light). I did not detect a central star.</p>
<p><b>NGC 6572</b> (Blue Racquetball) PN Oph 18h12m35.8s +06°51&#8242;28&#8243; 8.0 mag 09:40pm<br />
At 95x, this planetary nebula appears bright, stellar, and exhibits an obvious blue color. At 217x and 305x, the color is a bit washed out. At those magnifications, this planetary nebula appears very uniform, roughly 10&#8243; in diameter, and seems surrounded by a very faint envelope about 3 times the size of the nebula (unless this is scattered light). I did not detect a central star. There is a faint group of a dozen stars 10&#8242; west.</p>
<p><b>NGC 7217</b> GX Peg 22h08m20.6s +31°24&#8242;39&#8243; 11.1 mag 10:35pm<br />
Bright, round non stellar core surrounded by a larger, relatively bright uniform halo. Faint superimposed star less than 1&#8242; NNE of the core.</p>
<p><b>NGC 7814</b> GX Peg 00h03m47.1s +16°12&#8242;11&#8243; 11.6 mag 10:50pm<br />
Moderately bright and large. Appears roundish at first, progressively brighter toward its center. At higher magnification and with careful examination, a faint halo extending NW-SE can be detected. The bisecting dust lane obvious on photographs was not seen.</p>
<p><b>NGC 7448</b> GX Peg 23h00m34.6s +16°02&#8242;10&#8243; 12.1 mag 11:00pm<br />
Pretty small, moderately bright, elongated 2&#215;1 NNW-SSE, faint nucleus seen intermittently at high magnification. Suspected the detached segment that makes this galaxy peculiar to be at the northern tip of the galaxy.</p>
<p><b>Mayall II</b> (M31-G1) GC And 00h33m20.0s +39°38&#8242;04&#8243; 13.7 mag 12:20am<br />
Appears faint and stellar, thus requiring a very detailed chart to find! Forms a very tight triangle with two field stars. In order to confirm the observation, I sketched a few field stars along with the position of the presumed globular. The result is very close to the sketch published by Sue French in the December 2005 issue of Sky &#038; Telescope&#8217;s Deep Sky Wonder column. I believe that excellent seeing and high magnification are essential to see the non-stellar nature of this target.</p>
<p><b>NGC 205</b> (M 110) GX And 00h40m56.5s +41°44&#8242;30&#8243; 8.9 mag 12:30am<br />
Fairly large and bright, elongated 2&#215;1 NW-SE, gradually brighter to a stellar nucleus.</p>
<p><b>NGC 891</b> GX And 02h23m12.6s +42°23&#8242;30&#8243; 10.9 mag 12:45am<br />
Moderately faint, elongated roughly 6&#215;1 NNE-SSW, about 12&#8242; along its major axis. The dust lane splitting this galaxy in half is clearly visible only through the central bulge. Several fairly bright stars are superimposed. Peter Natscher&#8217;s 24&#8243; scope showed the bisecting dust lane much more clearly, along with some mottling.</p>
<p><b>NGC 7293</b> (Helix) PN Aqr 22h30m12.6s -20°47&#8242;05&#8243; 6.3 mag 12:55am<br />
Large, fairly dim, best seen using a UHC filter at low power. The ring structure, very slightly elongated NW-SE, can easily be seen. The NW and SE portions of the rim are clearly dimmer. A few superimposed stars, including what appears to be the central star, can be seen inside the ring over a faint background.</p>
<p><b>NGC 7662</b> (Blue Snowball) PN And 23h26m24.4s +42°35&#8242;30&#8243; 8.6 mag 01:30am<br />
At 95x, this planetary nebula appears bright, stellar, and looks slightly bluish. At 217x and 305x, the center region of the nebula appears darker, and an elliptical ring oriented roughly E-W can be detected. What I failed to see is the lumpy texture of the ring, beautifully documented in the October 2009 issue of Astronomy Now&#8217;s Drawn To The Universe column.</p>
<h3>Friday, September 18, 2009</h3>
<p><b>NGC 6822</b> (Barnard&#8217;s Galaxy) GX Sgr 19h45m32.4s -14°46&#8242;43&#8243; 9.4 mag 08:30pm<br />
Large (roughly 15&#8242; x 10&#8242;), elongated NNE-SSW, extremely pale, very easy to miss when sweeping the area, which is probably why this galaxy was missed by Herschel and was discovered so late (Barnard, 1881). There are a few superimposed stars throughout. A couple of small knots (probably HII regions) were seen using a UHC filter (although I did not note their position) This galaxy is part of the Local Group of galaxies.</p>
<p><b>NGC 7027</b> PN Cyg 21h07m25.2s +42°16&#8242;47&#8243; 9.6 mag 08:50pm<br />
Small, bright, exhibiting an obvious blue color, elongated 3:2 NW-SE, rectangular in shape, slightly wider on the NW side. A faint outer envelope, about twice the size of the nebula, was suspected (unless it could be scattered light)</p>
<p><b>NGC 6503</b> GX Dra 17h49m20.4s +70°08&#8242;46&#8243; 10.8 mag 09:15pm<br />
Fairly bright, moderately large, elongated 3&#215;1 WNW-ESE, fairly uniform with only a slight brightening of the core region. Detected a very weak nucleus or superimposed star.</p>
<p><b>NGC 7023</b> BN Cep 21h01m45.3s +68°12&#8242;26&#8243; mag 09:40pm<br />
Fairly dim nebulosity, roughly 2&#8242; in diameter, around V380 Cep (mag 7.4). Dim patch around 2 to 3&#8242; south of V380 Cep (photographs confirm the presence of this extension). A UHC filter makes the nebula disappear, confirming its reflective nature.</p>
<p><b>NGC 7479</b> GX Peg 23h05m28.0s +12°22&#8242;45&#8243; 11.7 mag 10:20pm<br />
Moderately bright, fairly small, elongated 5:2 N-S, weak fairly large core. Moderately bright (mag 12.9) superimposed star at the northern end, slightly dimmer (mag 13.7) star about 1&#8242; SW of the center. Suspected some mottling in the core. This galaxy is actually a barred spiral. The arms should be visible under better conditions and with a slightly larger scope.</p>
<p><b>NGC 7078</b> (M 15) GC Peg 21h30m28.0s +12°12&#8242;47&#8243; 6.3 mag 10:25pm<br />
Fairly large, very bright, very intense core, resolved throughout. Located about 7&#8242; SW of a bright (mag 7.6) star.</p>
<p><b>NGC 7099</b> (M 30) GC Cap 21h40m57.3s -23°07&#8242;56&#8243; 6.9 mag 10:35pm<br />
Moderately large and bright, well defined core, well resolved throughout. The SE region looks darker. Quite a few brighter stars are visible in the halo.</p>
<p><b>NGC 404</b> (Mirach&#8217;s Ghost) GX And 01h10m01.9s +35°46&#8242;21&#8243; 11.2 mag 11:00pm<br />
Located about 7&#8242; NW of Mirach (Beta And), a mag 2.0 star exhibiting a beautiful golden color. Moderately bright and small, round, gradually brighter to a fairly bright stellar nucleus best seen at high magnification.</p>
<p><b>NGC 628</b> (M 74) GX Psc 01h37m15.2s +15°50&#8242;11&#8243; 9.7 mag 11:35pm<br />
Fairly bright and small core embedded inside a large round faint halo showing hints of mottling at higher magnification. Very faint superimposed star within 1&#8242; ESE of the center, slightly brighter one about 1.5&#8242; ENE. Spiral structure better seen in Peter Natscher&#8217;s 24&#8243; scope.</p>
<p><b>NGC 7606</b> GX Aqr 23h19m37.3s -08°25&#8242;42&#8243; 11.7 mag 12:10am<br />
Moderately large and bright, elongated 2&#215;1 NNW-SSE, fairly bright stellar core, uniform halo.</p>
<p><b>NGC 7727</b> GX Aqr 23h40m26.2s -12°14&#8242;02&#8243; 11.6 mag 12:20am<br />
Fairly small and bright, small round intense core, round uniform halo. NGC 7723 and NGC 7724 nearby.</p>
<p><b>NGC 7723</b> GX Aqr 23h39m29.4s -12°54&#8242;15&#8243; 11.9 mag 12:25am<br />
Fairly small, moderately faint, moderately bright stellar nucleus surrounded by a fairly uniform halo elongated 3:2 NE-SW. Located about 20&#8242; ENE of a bright yellow double star. NGC 7727 and NGC 7724 nearby.</p>
<p><b>NGC 253</b> (Sculptor Galaxy) GX Scl 00h48m04.1s -25°13&#8242;53&#8243; 7.9 mag 12:45am<br />
Very easily seen along globular cluster NGC 288 in 9&#215;50 finder scope. Very large and bright, elongated 6&#215;1 NE-SW. The core region is large, bright, and shows some obvious mottling (seen even better in Peter Natscher&#8217;s 24&#8243; scope). Numerous fairly bright field stars are superimposed.</p>
<p><b>NGC 247</b> GX Cet 00h47m39.8s -20°42&#8242;11&#8243; 9.7 mag 12:55am<br />
Pretty large, moderately faint, elongated 6&#215;1 N-S, very weak central condensation. Fairly bright (mag 9.5) star at the southern tip, moderately bright (mag 11.6) superimposed star about 7&#8242; S.</p>
<p><b>NGC 288</b> GC Scl 00h53m15.8s -26°31&#8242;34&#8243; 8.1 mag 01:00am<br />
Very easily seen along galaxy NGC 253 in 9&#215;50 finder scope. Fairly large and bright, fairly uniform, well resolved throughout.</p>
<p><b>NGC 613</b> GX Scl 01h34m47.8s -29°21&#8242;46&#8243; 10.7 mag 01:10am<br />
Moderately large and bright, elongated 3&#215;1 NW-SE, fairly bright small round core. Hints of two spiral arms, one starting at the NW end, bending towards the W, and a symmetrical arm starting at the SE end, bending towards the E.</p>
<p><b>NGC 7793</b> GX Scl 23h58m22.3s -32°32&#8242;00&#8243; 9.7 mag 01:15am<br />
Moderately large, fairly faint, elongated 4:3 E-W, faint almost stellar core.</p>
<p><b>NGC 524</b> GX Psc 01h25m20.5s +09°35&#8242;35&#8243; 11.4 mag 01:30am<br />
Bright, fairly small. Intense core surrounding an almost stellar nucleus. Fairly bright round halo. Brightest member of the Shakhbazian 40 group.</p>
<p><b>NGC 1023</b> GX Per 02h41m02.8s +39°06&#8242;23&#8243; 9.6 mag 01:35am<br />
Moderately large, fairly bright, small bright round core, halo elongated 2&#215;1 E-W. Two faint superimposed stars about 1&#8242; W of the center, and one faint superimposed star about 1&#8242; E. The companion NGC 1023A was not seen.</p>
<p><b>NGC 488</b> GX Psc 01h22m19.2s +05°18&#8242;41&#8243; 11.1 mag 02:00am<br />
Fairly small and bright, bright round core surrounded by a halo very slightly elongated N-S.</p>
<p><b>NGC 185</b> GX Cas 00h39m32.8s +48°23&#8242;36&#8243; 10.2 mag 02:15am<br />
This is a satellite of M31. Fairly large, pretty uniform, large faint core surrounded by a halo elongated 4:3 NNE-SSE. Located in a crowded region of the milky way. Could not detect the dust patch seen on photographs.</p>
<p><b>NGC 278</b> GX Cas 00h52m39.9s +47°36&#8242;20&#8243; 11.5 mag 02:30am<br />
Fairly small, pretty bright, fairly bright stellar nucleus, round uniform halo. Located about 3&#8242; S of a bright (mag 8.8) field star.</p>]]></content:encoded>
         <category>Astronomy</category>
      </item>
      <item>
         <title>A Better Implementation Of The Input Prompt Pattern</title>
         <link>http://www.julienlecomte.net/blog/2009/09/314/</link>
         <description>The Input Prompt pattern consists in prefilling a text field with a prompt as a way of supplying help information for controls whose purpose or format may not be immediately clear. In the browser, this pattern is most often implemented by dynamically modifying the value property of a text field element via the focus and [...]</description>
         <guid isPermaLink="false">http://www.julienlecomte.net/blog/?p=314</guid>
         <pubDate>Mon, 14 Sep 2009 11:43:01 -0700</pubDate>
         <content:encoded><![CDATA[<p>The Input Prompt pattern consists in prefilling a text field with a prompt as a way of supplying help information for controls whose purpose or format may not be immediately clear. In the browser, this pattern is most often implemented by dynamically modifying the <code>value</code> property of a text field element via the <code>focus</code> and <code>blur</code> event handlers attached to the text field, as shown in this example (<a rel="nofollow">live demo</a>):</p>
<p>CSS:</p>
<pre class="prettyprint"><code>.hint { color: #999;
}</code></pre>
<p>Markup:</p>
<pre class="prettyprint"><code>&#60;input type="text" id="sbx"&#62;</code></pre>
<p>JavaScript (based on YUI 3.0.0):</p>
<pre class="prettyprint"><code>YUI().use('node', function (Y) { var sbx = Y.get('#sbx'); Y.on('domready', function () { sbx.set('value', 'Search'); sbx.addClass('hint'); Y.on('focus', function () { if (this.get('value') === 'Search') { this.set('value', ''); this.removeClass('hint'); } }, sbx); Y.on('blur', function () { if (this.get('value') === '') { this.set('value', 'Search'); this.addClass('hint'); } }, sbx); });
});</code></pre>
<p><strong>Note:</strong> the code is intentionally implemented inside a <code>domready</code> event handler to work around issues related to form field caching.</p>
<p>The main problem with implementing this pattern using the <code>value</code> property is that the default text is used if the form is submitted while the input prompt is showing. Trying to work around this by testing the content of the text field when the form is submitted makes the default text impossible to use as a value. Another side effect of this implementation is that most developers will forget to attach a <code>&lt;label&gt;</code> element to the text field, leading to a confusing experience for screen reader users as they lack the necessary context to understand the purpose of the control.</p>
<p>A better implementation of this pattern consists in using a <code>&lt;label&gt;</code> element and positioning it on top of the text field it is attached to. Here is an example of this implementation (<a rel="nofollow">live demo</a>):</p>
<p>CSS:</p>
<pre class="prettyprint"><code>#container { position: relative;
} #container label { position: absolute; top: 4px; *top: 6px; left: 3px; color: #999; cursor: text;
} #container label.offscreen { left: -9999px;
}</code></pre>
<p>Markup:</p>
<pre class="prettyprint"><code>&#60;div id="container"&#62; &#60;label for="sbx" class="offscreen"&gt;Search&#60;/label&#62; &#60;input type="text" id="sbx"&#62;
&#60;/div&#62;</code></pre>
<p>JavaScript (based on YUI 3.0.0):</p>
<pre class="prettyprint"><code>YUI().use('node', function (Y) { var sbx = Y.get('#sbx'), lbl = Y.get('#container label'); Y.on('domready', function () { sbx.set('value', ''); lbl.removeClass('offscreen'); Y.on('mousedown', function () { setTimeout(function () { sbx.focus(); }, 0); }, lbl); Y.on('focus', function () { lbl.addClass('offscreen'); }, sbx); Y.on('blur', function () { if (sbx.get('value') === '') { sbx.set('value', ''); lbl.removeClass('offscreen'); } }, sbx); });
});</code></pre>
<p>As always, I am looking forward to reading your comments and answering your questions in the comments section of this blog.</p>]]></content:encoded>
         <category>Web Development</category>
      </item>
      <item>
         <title>OR: Henry Coe State Park, 8/15/09</title>
         <link>http://www.julienlecomte.net/blog/2009/08/296/</link>
         <description>A lot of people showed up for some stargazing at the overflow parking lot at Henry Coe state park. The conditions were pretty good overall: Light winds coming from the north west
Temperature in the high to mid 60s
Good seeing
Average transparency While waiting for the sky to turn dark, I pointed my scope toward Antares, which was showing [...]</description>
         <guid isPermaLink="false">http://www.julienlecomte.net/blog/?p=296</guid>
         <pubDate>Mon, 17 Aug 2009 11:07:17 -0700</pubDate>
         <content:encoded><![CDATA[<p>A lot of people showed up for some stargazing at the overflow parking lot at Henry Coe state park. The conditions were pretty good overall:</p>
<ul>
<li>Light winds coming from the north west</li>
<li>Temperature in the high to mid 60s</li>
<li>Good seeing</li>
<li>Average transparency</li>
</ul>
<p>While waiting for the sky to turn dark, I pointed my scope toward Antares, which was showing a fairly clean split while still high in the southern sky. The dim companion, a white dwarf, was located just to the west of the red giant.</p>
<p>I then spent most of the evening tracking down some bright targets from the Herschel 400 list. Among the highlights, the Saturn nebula (NGC 7009) was showing a lot of details (see description below)</p>
<p>Before wrapping up around 1am, I looked at Jupiter. The view was absolutely incredible, although the wind proved to be a bit of a problem with my light weight scope. The great red spot was more colorful than I can ever remember. Its color used to be a very delicate pink mixed with a little bit of gray a few years ago. But this time, it was definitely orange. A lot of tiny details could be spotted throughout the bands, and even in the polar regions! What a view to behold!</p>
<p>Here are my observations. Overall, it was a good night, and I&#8217;m glad I went out. Cheers!</p>
<p>Location: Henry Coe state park [Elevation 2600 ft]<br />
Telescope: Meade Lightbridge 12&#8243; F/5<br />
Eyepieces used:<br />
- Televue Panoptic 27mm (56x – 1.2° TFOV)<br />
- Televue Nagler 16mm type 5 (95x – 52&#8242; TFOV)<br />
- Televue Nagler 9mm type 6 (169x – 29&#8242; TFOV)<br />
- Televue Nagler 7mm type 6 (217x – 22&#8242; TFOV)<br />
- Televue Nagler 5mm type 6 (305x – 16&#8242; TFOV)<br />
(All times are PDT)</p>
<p><img src="http://www.julienlecomte.net/blogfiles/20090815/ngc7128.jpg" style="width:90px;height:90px;float:left;margin-right:10px;" alt="NGC 7128"></p>
<p><b>NGC 7128</b> OC Cyg 21h44m19.3s +53°45&#8242;39&#8243; 11.3 mag 09:30p<br />
About 15 moderately bright stars within an area roughly 4&#8242; x 2&#8242; elongated NE-SW. The brightest star, located NE of the cluster, shows a nice orange/reddish color.</p>
<p><br style="clear:both;line-height:0;"/></p>
<p><img src="http://www.julienlecomte.net/blogfiles/20090815/ngc7086.jpg" style="width:90px;height:90px;float:left;margin-right:10px;" alt="NGC 7086"></p>
<p><b>NGC 7086</b> OC Cyg 21h30m49.2s +51°38&#8242;39&#8243; 11.6 mag 09:40p<br />
About 50 moderately bright stars within 10&#8242;.</p>
<p><br style="clear:both;line-height:0;"/></p>
<p><img src="http://www.julienlecomte.net/blogfiles/20090815/ngc7062.jpg" style="width:90px;height:90px;float:left;margin-right:10px;" alt="NGC 7062"></p>
<p><b>NGC 7062</b> OC Cyg 21h23m50.4s +46°25&#8242;18&#8243; 8.3 mag 09:45p<br />
About two dozen moderately bright to moderately faint stars located within 5&#8242;. Slightly elongated E-W.</p>
<p><br style="clear:both;line-height:0;"/></p>
<p><img src="http://www.julienlecomte.net/blogfiles/20090815/ngc7006.jpg" style="width:90px;height:90px;float:left;margin-right:10px;" alt="NGC 7006"></p>
<p><b>NGC 7006</b> GC Del 21h01m58.1s +16°13&#8242;44&#8243; 10.6 mag 09:50p<br />
Small, faint, small fairly bright core, fairly faint halo, unresolved.</p>
<p><br style="clear:both;line-height:0;"/></p>
<p><img src="http://www.julienlecomte.net/blogfiles/20090815/ngc7009.jpg" style="width:90px;height:90px;float:left;margin-right:10px;" alt="NGC 7009"></p>
<p><b>NGC 7009</b> (Saturn Nebula) PN Aqr 21h04m44.6s -11°19&#8242;22&#8243; 8.3 mag 10:30p<br />
At low power (95x), this planetary nebula appears small, fairly bright, elongated 3:2 WNW-ESE, and exhibits a delicate blue/green color. At higher magnification (217x and 305x), the center of the nebula appears very slightly darker. Faint extensions show up on both sides of the oval disk, terminated by a tiny slightly brighter knot. The extension on the ESE side seems to slightly bend toward the NE. Finally, during brief moments of better seeing, a ring elongated 2:1 appears inside the nebula. The central star was not detected.</p>
<p><br style="clear:both;line-height:0;"/></p>
<p><img src="http://www.julienlecomte.net/blogfiles/20090815/ngc6940.jpg" style="width:90px;height:90px;float:left;margin-right:10px;" alt="NGC 6940"></p>
<p><b>NGC 6940</b> OC Vul 20h34m52.3s +28°19&#8242;09&#8243; 7.2 mag 10:45p<br />
About 80 stars within an area 25&#8242; x 10&#8242; elongated WNW-ESE. Orange star in the center.</p>
<p><br style="clear:both;line-height:0;"/></p>
<p><img src="http://www.julienlecomte.net/blogfiles/20090815/ngc6885.jpg" style="width:90px;height:90px;float:left;margin-right:10px;" alt="NGC 6885"></p>
<p><b>NGC 6885</b> OC Vul 20h12m27.3s +26°30&#8242;35&#8243; 5.7 mag 10:50p<br />
Sparse cluster of roughly 20 fairly bright stars within an area 20&#8242; in diameter, centered around 20 Vul (mag 5.9) Another open cluster, NGC 6882, is embedded inside NGC 6885.</p>
<p><br style="clear:both;line-height:0;"/></p>
<p><img src="http://www.julienlecomte.net/blogfiles/20090815/ngc6882.jpg" style="width:90px;height:90px;float:left;margin-right:10px;" alt="NGC 6882"></p>
<p><b>NGC 6882</b> OC Vul 20h12m13.2s +26°50&#8242;35&#8243; 10:50p<br />
About 20 moderately bright stars within an area roughly 10&#8242; in diameter located about 10&#8242; NW of 20 Vul (mag 5.9), and inside another open cluster, NGC 6885.</p>
<p><br style="clear:both;line-height:0;"/></p>
<p><img src="http://www.julienlecomte.net/blogfiles/20090815/ngc6939.jpg" style="width:90px;height:90px;float:left;margin-right:10px;" alt="NGC 6939"></p>
<p><b>NGC 6939</b> OC Cep 20h31m44.1s +60°41&#8242;48&#8243; 10.1 mag 11:10p<br />
About 80 moderately bright stars within an area roughly 10&#8242; in diameter. The southern boundary seems delimited by an almost perfect alignment of 5 brighter stars. Slight triangular shape, like an arrow moving west&#8230; Forms a superb couple with galaxy NGC 6946. Both objects can be seen within the 1.2 degree field of view of the Panoptic 27mm.</p>
<p><br style="clear:both;line-height:0;"/></p>
<p><img src="http://www.julienlecomte.net/blogfiles/20090815/ngc7160.jpg" style="width:90px;height:90px;float:left;margin-right:10px;" alt="NGC 7160"></p>
<p><b>NGC 7160</b> OC Cep 21h53m59.4s +62°39&#8242;00&#8243; 6.4 mag 11:40p<br />
About 20 fairly bright stars scattered within an area roughly 5&#8242; in diameter, centered around two very bright stars (mag 7.0 and 7.9) separated by about 1&#8242;.</p>
<p><br style="clear:both;line-height:0;"/></p>
<p><img src="http://www.julienlecomte.net/blogfiles/20090815/ngc7380.jpg" style="width:90px;height:90px;float:left;margin-right:10px;" alt="NGC 7380"></p>
<p><b>NGC 7380</b> OC Cep 22h47m46.7s +58°11&#8242;00&#8243; 8.8 mag 12:40a<br />
About 30 moderately bright stars within 15&#8242;. Apparently, this cluster is embedded inside a nebula (Sh 2-142) but I did not notice anything, and since I was not aware of it, I did not think of trying a narrow-band filter.</p>
<p><br style="clear:both;line-height:0;"/></p>
<p><img src="http://www.julienlecomte.net/blogfiles/20090815/ngc7510.jpg" style="width:90px;height:90px;float:left;margin-right:10px;" alt="NGC 7510"></p>
<p><b>NGC 7510</b> OC Cep 23h11m30.4s +60°37&#8242;22&#8243; 9.3 mag 12:45a<br />
About 20 moderately bright to moderately faint stars within an area 5&#8242; x 2&#8242; elongated WSW-ENE.</p>
<p><br style="clear:both;line-height:0;"/></p>
<p><img src="http://www.julienlecomte.net/blogfiles/20090815/ngc40.jpg" style="width:90px;height:90px;float:left;margin-right:10px;" alt="NGC 40"></p>
<p><b>NGC 40</b> PN Cep 00h13m36.3s +72°34&#8242;28&#8243; 10.7 mag 01:00a<br />
Moderately large and bright, fairly bright central star, very slightly elongated NNE-SSW. Appears pretty uniform at first. With careful examination, the southern region of the nebula shows a slight darkening. The rim is fairly well defined, and slightly brighter than the disk itself. Superimposed star on the SSW rim.</p>
<p><br style="clear:both;line-height:0;"/></p>]]></content:encoded>
         <category>Astronomy</category>
      </item>
      <item>
         <title>OR: D.A.R.C. Observatory, 7/25/2009</title>
         <link>http://www.julienlecomte.net/blog/2009/07/288/</link>
         <description>I went to the D.A.R.C. observatory last Saturday to observe or re-observe a few Herschel 400 summer objects, as well as enjoy some eye candy under a dark sky. I was setup right next to Dennis Beckley and his classic Obsession 18&amp;#8243;. Here is a summary of the weather conditions: Wind died down shortly after sunset
Temperature [...]</description>
         <guid isPermaLink="false">http://www.julienlecomte.net/blog/?p=288</guid>
         <pubDate>Mon, 27 Jul 2009 16:11:29 -0700</pubDate>
         <content:encoded><![CDATA[<p>I went to the D.A.R.C. observatory last Saturday to observe or re-observe a few Herschel 400 summer objects, as well as enjoy some eye candy under a dark sky. I was setup right next to Dennis Beckley and his classic Obsession 18&#8243;. Here is a summary of the weather conditions:</p>
<ul>
<li>Wind died down shortly after sunset</li>
<li>Temperature in the low 70s</li>
<li>Good seeing (6 to 7 on the Pickering scale)</li>
<li>Average transparency (the light dome from Los Banos, which I use as an indication of the moisture content in the atmosphere, was fairly conspicuous)</li>
<li>NELM 6.7 in Lyra</li>
<li>Thin clouds started showing up around 1am from the east</li>
</ul>
<p>Overall, it was a pretty good night, although not as good as what the D.A.R.C. observatory has proven capable of. Among the highlights of the night, I got to observe Triton for the first time. The Jupiter impact mark was seen very easily, and Jupiter&#8217;s satellites were resolved as tiny discs of different diameters. The &#8220;ink spot&#8221; (Barnard 86 located right next to OC NGC 6520) looked absolutely remarkable. Stephan&#8217;s quintet was looking pretty good in my scope, and was easy in Dennis&#8217; 18&#8243; scope. Finally, I really enjoyed looking at V Aql, a fairly bright carbon star of deep orange color with a tinge of red. What is interesting about this star, beyond its striking color, is the presence of planetary nebula NGC 6751 about 30&#8242; SE. It is therefore possible to fit both objects within the same field of view in modest amateur telescopes (8 to 12&#8243;), portraying two stages of stellar evolution as the carbon star will eventually become a planetary nebula in a not so distant future.</p>
<p>On Sunday morning, I had an immense satisfaction when I looked at a DSS image of galaxy NGC 6217 (Arp 185), and noticed that my notes (see below) were absolutely right on! I find it absolutely amazing that such wispy details can be detected with such a small aperture under a good dark sky.</p>
<p>I cannot end this report without thanking Dr. Lee Hoglan for letting us observe on his property. Below is my log for the night. Cheers!</p>
<p>Location: D.A.R.C. Observatory [Elevation 1400ft]<br />
Telescope: Meade Lightbridge 12&#8243; F/5<br />
Eyepieces used:<br />
- Televue Panoptic 27mm (56x &#8211; 1.2° TFOV)<br />
- Televue Nagler 16mm type 5 (95x &#8211; 52&#8242; TFOV)<br />
- Televue Nagler 9mm type 6 (169x &#8211; 29&#8242; TFOV)<br />
- Televue Nagler 7mm type 6 (217x &#8211; 22&#8242; TFOV)<br />
- Televue Nagler 5mm type 6 (305x &#8211; 16&#8242; TFOV)<br />
(All times in PDT)</p>
<p><img src="http://www.julienlecomte.net/blogfiles/20090725/ngc6217.jpg" style="width:90px;height:90px;float:left;margin-right:10px;" alt="NGC 6217"></p>
<p><b>NGC 6217</b> GX UMi 16h32m15.6s +78°10&#8242;52&#8243; 11.9 mag 10:15p<br />
Small, faint, elongated 3:2 NW-SE, fairly faint stellar core or super imposed star. Very faint super imposed star about 20&#8243; SE, another one about 2.5&#8242; NW. Hints of two spiral arms, one on the N side going E, and another one on the S side going W. This observation was later beautifully confirmed with a DSS image.</p>
<p><br style="clear:both;line-height:0;"/></p>
<p><img src="http://www.julienlecomte.net/blogfiles/20090725/ngc6834.jpg" style="width:90px;height:90px;float:left;margin-right:10px;" alt="NGC 6834"></p>
<p><b>NGC 6834</b> OC Cyg 19h52m37.2s +29°26&#8242;04&#8243; 9.7 mag 10:30p<br />
Seen as a tiny smudge in a 9&#215;50 finder scope. Small grouping of about 30 moderately bright stars. One brighter star in the middle, with a possible slight yellow tinge. Located in a region with relatively few stars (dark nebula?) in an otherwise crowded milky way star field. For some reason, I found it hard to star-hop to&#8230;</p>
<p><br style="clear:both;line-height:0;"/></p>
<p><img src="http://www.julienlecomte.net/blogfiles/20090725/ngc6866.jpg" style="width:90px;height:90px;float:left;margin-right:10px;" alt="NGC 6866"></p>
<p><b>NGC 6866</b> OC Cyg 20h04m16.1s +44°11&#8242;11&#8243; 9.1 mag 10:40p<br />
About 30 fairly bright stars within a region 15&#8242; in diameter. Detected in 9&#215;50 finder scope.</p>
<p><br style="clear:both;line-height:0;"/></p>
<p><img src="http://www.julienlecomte.net/blogfiles/20090725/ngc6910.jpg" style="width:90px;height:90px;float:left;margin-right:10px;" alt="NGC 6910"></p>
<p><b>NGC 6910</b> OC Cyg 20h23m34.7s +40°48&#8242;37&#8243; 7.3 mag 10:45p<br />
Small group of about 15 stars, elongated 2&#215;1 WNW-ESE (dimensions: 10&#8242; x 5&#8242;) The two brightest stars have a yellow tinge. Located about 30&#8242; N of Gamma Cyg (Sadr)</p>
<p><br style="clear:both;line-height:0;"/></p>
<p><img src="http://www.julienlecomte.net/blogfiles/20090725/ngc7044.jpg" style="width:90px;height:90px;float:left;margin-right:10px;" alt="NGC 7044"></p>
<p><b>NGC 7044</b> OC Cyg 21h13m32.8s +42°32&#8242;06&#8243; 12.0 mag 10:50p<br />
Small compact group of maybe 50 faint stars (hard to get a reliable star count) scattered within a circular region of about 5&#8242; in diameter.</p>
<p><br style="clear:both;line-height:0;"/></p>
<p><img src="http://www.julienlecomte.net/blogfiles/20090725/ngc6522.jpg" style="width:90px;height:90px;float:left;margin-right:10px;" alt="NGC 6522"></p>
<p><b>NGC 6522</b> GC Sgr 18h04m14.3s -30°02&#8242;08&#8243; 9.9 mag 11:00p<br />
Fairly small, moderately faint, fairly well defined core, halo appears grainy. There is a moderately bright star located about 30&#8243; E which probably does not belong to this cluster. Forms a beautiful couple with globular cluster NGC 6528 located about 15&#8242; E.</p>
<p><br style="clear:both;line-height:0;"/></p>
<p><img src="http://www.julienlecomte.net/blogfiles/20090725/ngc6528.jpg" style="width:90px;height:90px;float:left;margin-right:10px;" alt="NGC 6528"></p>
<p><b>NGC 6528</b> GC Sgr 18h05m28.3s -30°03&#8242;25&#8243; 9.6 mag 11:00p<br />
Fairly small, moderately faint, fairly well defined core, unresolved. Located at the NW edge of B298. Forms a beautiful couple with globular cluster NGC 6522 located about 15&#8242; W. This cluster is slightly dimmer than its neighbor NGC 6522 (some of its light may be absorbed by B298?)</p>
<p><br style="clear:both;line-height:0;"/></p>
<p><img src="http://www.julienlecomte.net/blogfiles/20090725/ngc6818.jpg" style="width:90px;height:90px;float:left;margin-right:10px;" alt="NGC 6818"></p>
<p><b>NGC 6818</b> PN Sgr 19h44m32.6s -14°07&#8242;45&#8243; 10.0 mag 11:25p<br />
Tiny fairly bright disk, almost circular (extremely slightly elongated NS) showing a delicate bluish tinge, especially at low power. At higher magnification, the center of the nebula appears very slightly darker. The central star (mag 15.0) was not seen. Located inside a small triangle of moderately bright stars.</p>
<p><br style="clear:both;line-height:0;"/></p>
<p><img src="http://www.julienlecomte.net/blogfiles/20090725/ngc6664.jpg" style="width:90px;height:90px;float:left;margin-right:10px;" alt="NGC 6664"></p>
<p><b>NGC 6664</b> OC Sct 18h37m10.4s -07°48&#8242;17&#8243; 8.5 mag 11:45p<br />
About 60 moderately faint stars within 15&#8242;. This cluster appears slightly elongated N-S, and is located about 25&#8242; NE of Alpha Sct, which has a fairly distinctive yellow tinge.</p>
<p><br style="clear:both;line-height:0;"/></p>
<p><img src="http://www.julienlecomte.net/blogfiles/20090725/ngc6712.jpg" style="width:90px;height:90px;float:left;margin-right:10px;" alt="NGC 6217"></p>
<p><b>NGC 6712</b> GC Sct 18h53m37.6s -08°41&#8242;33&#8243; 8.1 mag 11:50p<br />
Moderately large and bright with a poorly defined core region. Many stars are resolved over a milky background.</p>
<p><br style="clear:both;line-height:0;"/></p>
<p><img src="http://www.julienlecomte.net/blogfiles/20090725/ngc6802.jpg" style="width:90px;height:90px;float:left;margin-right:10px;" alt="NGC 6802"></p>
<p><b>NGC 6802</b> OC Vul 19h31m02.2s +20°16&#8242;59&#8243; 11.7 mag 12:50a<br />
Small (5&#8242; x 2&#8242;) compact group of about 25 very faint stars, elongated N-S. Located just east of the famous coat hanger asterism (Cr 399)</p>
<p><br style="clear:both;line-height:0;"/></p>
<p><img src="http://www.julienlecomte.net/blogfiles/20090725/ngc6823.jpg" style="width:90px;height:90px;float:left;margin-right:10px;" alt="NGC 6823"></p>
<p><b>NGC 6823</b> OC Vul 19h43m35.6s +23°19&#8242;27&#8243; 7.1 mag 12:55a<br />
About 30 fairly bright stars scattered within 6&#8242; around a small group of 4 bright stars and a few fainter ones. Not very conspicuous in a crowded star field. Nearby nebula NGC 6820 was not seen (although I did not really look for it and thus was not using a nebula filter)</p>
<p><br style="clear:both;line-height:0;"/></p>
<p><img src="http://www.julienlecomte.net/blogfiles/20090725/ngc6830.jpg" style="width:90px;height:90px;float:left;margin-right:10px;" alt="NGC 6830"></p>
<p><b>NGC 6830</b> OC Vul 19h51m25.8s +23°07&#8242;33&#8243; 8.9 mag 01:00a<br />
Very inconspicuous grouping of about 20 fairly bright stars.</p>
<p><br style="clear:both;line-height:0;"/></p>
<p><img src="http://www.julienlecomte.net/blogfiles/20090725/ngc6934.jpg" style="width:90px;height:90px;float:left;margin-right:10px;" alt="NGC 6934"></p>
<p><b>NGC 6934</b> GC Del 20h34m41.3s +07°26&#8242;22&#8243; 8.9 mag 02:00a<br />
Relatively small, fairly bright, intense core. A great number of stars are resolved throughout at 217x.</p>
<p><br style="clear:both;line-height:0;"/></p>]]></content:encoded>
         <category>Astronomy</category>
      </item>
      <item>
         <title>Test Suites for CSS 2.1, ARIA, and HTML5</title>
         <link>http://nate.koechley.com/blog/2009/01/27/test-suites-for-css-21-aria-and-html5/</link>
         <description>Just hours ago Microsoft released an amazing new resource that helps the entire frontend engineering industry. Their Windows Internet Explorer Testing Center contains thousands of test cases covering CSS 2.1, HTML5, and WAI-ARIA.
CSS gets the most coverage with 7005 tests, 3784 of them developed just since IE8&amp;#8217;s &amp;#8220;beta 2&amp;#8243; a few months ago. IE8 passes [...]</description>
         <guid isPermaLink="false">http://nate.koechley.com/blog/?p=511</guid>
         <pubDate>Tue, 27 Jan 2009 23:43:59 -0800</pubDate>
         <content:encoded><![CDATA[<p>Just hours ago Microsoft released an amazing new resource that helps the entire frontend engineering industry. Their <a rel="nofollow" target="_blank" href="http://samples.msdn.microsoft.com/ietestcenter/">Windows Internet Explorer Testing Center</a> contains thousands of test cases covering CSS 2.1, HTML5, and WAI-ARIA.</p>
<p>CSS gets the most coverage with 7005 tests, 3784 of them developed just since IE8&#8217;s &#8220;beta 2&#8243; a few months ago. IE8 passes all 7005, <strong>including, mysteriously, 52 tests that do not pass on any other major browser</strong>.</p>
<p>For HTML5, coverage includes 13 cross-document messaging and 30 DOM Storage tests. For WAI &#8211; ARIA they submitted new samples to support their previously-submitted ARIA to MSAA roles, events, and mappings. </p>
<p>While a great resource for the standardization movement in general, it also goes a long way to support <a rel="nofollow" target="_blank" href="http://blogs.msdn.com/ie/archive/2009/01/27/microsoft-submits-thousands-more-css-2-1-tests-to-the-w3c.aspx">their stated belief</a> that &#8220;IE8 RC1 has the most complete implementation of the CSS 2.1 specification in the industry.&#8221; It will be very interesting to see if any of the other browsers care to comment. I&#8217;m hoping for a four-way tie.</p>
<p>Read more:</p>
<ul>
<li><a rel="nofollow" target="_blank" href="http://blogs.msdn.com/ie/archive/2009/01/27/microsoft-submits-thousands-more-css-2-1-tests-to-the-w3c.aspx.">IEBlog &#8211; Microsoft submits thousands more CSS 2.1 tests to the W3C</a></li>
<li><a rel="nofollow" target="_blank" href="http://samples.msdn.microsoft.com/ietestcenter/">Windows Internet Explorer Testing Center</a></li>
<li><a rel="nofollow" target="_blank" href="http://samples.msdn.microsoft.com/ietestcenter/aria.htm">ARIA Test Pages</a></li>
<li><a rel="nofollow" target="_blank" href="http://samples.msdn.microsoft.com/ietestcenter/css.htm">CSS 2.1 Test Pages</a></li>
<li><a rel="nofollow" target="_blank" href="http://samples.msdn.microsoft.com/ietestcenter/html5.htm">HTML 5 Test Pages</a></li>
</ul>]]></content:encoded>
      </item>
      <item>
         <title>The Eyeballing Game</title>
         <link>http://nate.koechley.com/blog/2008/10/16/the-eyeballing-game/</link>
         <description>Here&amp;#8217;s an enjoyable way to spend ten minutes giving your brain some exercise: The Eyeballing Game. The game/exercise asks you to modify a polygon to create a parallelogram and right angle, find the midpoint of a line, bisect an angle, find the center or a triangle and circle, and identify a convergence point. My average [...]</description>
         <guid isPermaLink="false">http://nate.koechley.com/blog/?p=510</guid>
         <pubDate>Thu, 16 Oct 2008 11:55:15 -0700</pubDate>
         <content:encoded><![CDATA[<p>Here&#8217;s an enjoyable way to spend ten minutes giving your brain some exercise: <a rel="nofollow" target="_blank" href="http://woodgears.ca/eyeball/">The Eyeballing Game</a>. The game/exercise asks you to modify a polygon to create a parallelogram and right angle, find the midpoint of a line, bisect an angle, find the center or a triangle and circle, and identify a convergence point. </p>
<p>My average score, the degree on inaccuracy, (as you can see below) was 4.01 (low is better). By best showing was bisecting an angle. </p>
<p>Think you can do better? Give it a shot: <a rel="nofollow" target="_blank" href="http://woodgears.ca/eyeball/">http://woodgears.ca/eyeball/</a></p>
<p><img src="http://nate.koechley.com/screencaps/my-eyeballing-game-distribution-20081016-113541.png" alt="my-eyeballing-game-distribution"/></p>
<p><img src="http://nate.koechley.com/screencaps/my-inaccuracy-by-category-20081016-115135.png" alt="my-inaccuracy-by-category"/> </p>]]></content:encoded>
      </item>
      <item>
         <title>Walking for Farm Animals</title>
         <link>http://nate.koechley.com/blog/2008/10/11/walking-for-farm-animals/</link>
         <description>This weekend, Aimee and I are taking part in the Walk for Farm Animals 2008 to raise money for Farm Sanctuary, a national non-profit that works to end cruelty to farm and food animals through rescue, education, and advocacy. It&amp;#8217;s a great organization that, to me, is way more palatable than more confrontational organizations [...]</description>
         <guid isPermaLink="false">http://nate.koechley.com/blog/?p=508</guid>
         <pubDate>Sat, 11 Oct 2008 10:55:53 -0700</pubDate>
         <content:encoded><![CDATA[<p>This weekend, Aimee and I are taking part in the <em>Walk for Farm Animals 2008</em> to raise money for <a rel="nofollow" target="_blank" href="http://www.farmsanctuary.org/">Farm Sanctuary</a>, a national non-profit that works to end cruelty to farm and food animals through rescue, education, and advocacy. It&#8217;s a great organization that, to me, is way more palatable than more confrontational organizations such as PETA.</p>
<p><a rel="nofollow" target="_blank" href="http://www.firstgiving.com/aimee-n-nate">We hope you&#8217;ll support us by donating $5-10 (or more) via our FirstGiving page</a> (a secure way to send directly to Farm Sanctuary, and they&#8217;ll mail you a tax-deductible receipt).</p>
<p><a rel="nofollow" target="_blank" href="http://www.flickr.com/photos/aimeebell/sets/72157607916178771/"><br />
<img src="http://nate.koechley.com/screencaps/goat-20081011-105242.png" alt="goat at farm sanctuary" align="left"/></a></p>
<p>We visited Farm Sanctuary&#8217;s California farm in Orland last weekend (they have one on NY, too). We stayed in the farm&#8217;s guest cabin and were able to spend a lot of time with all the animals (Aimee discovered I&#8217;m something of a turkey whisperer). It was fun to see them in action and we had a chance to volunteer a little by preparing food and feeding many of the animals and brushing the goats.</p>
<p><a rel="nofollow" target="_blank" href="http://www.flickr.com/photos/aimeebell/sets/72157607916178771/">Aimee posted a set of photos (ad 2 vids) from our time at Farm Sanctuary on Flickr</a>.</p>
<p><a rel="nofollow" target="_blank" href="http://www.flickr.com/photos/aimeebell/sets/72157607916178771/"><img src="http://nate.koechley.com/screencaps/Flickr_Photo_Download__Happy_Pig_burrowing_in_hay_after_a_big_meal-20081011-105125.png" alt="happy pig at farm sanctuary" align="right"/></a></p>
<p>Also, if you vote in California, <a rel="nofollow" target="_blank" href="http://www.yesonprop2.com">please join us in supporting Prop 2</a> (sponsored by Farm Sanctuary) with a &#8220;Yes&#8221; vote in November. </p>
<p>Prop 2 is a modest measure that would allow farm and food animals the ability to stand up, stretch and turn around. Through the reduction of these inhumane caging/crating practices (most commonly used by factory farms) will improve the health and safety of our food, support family farmers, and reduce the environmental degradation caused by these unnecessary practices. The <a rel="nofollow" target="_blank" href="http://www.nytimes.com/2008/10/09/opinion/09thu3.html">NY Times has endorsed Prop 2</a> in a thoughtful and straightforward article. </p>
<p>We hope you enjoy our pictures and <a rel="nofollow" target="_blank" href="http://www.firstgiving.com/aimee-n-nate">hope you&#8217;ll consider helping us raise money for this important organization</a>.</p>
<p>Thanks and love,<br />
nate &amp; aimee</p>]]></content:encoded>
      </item>
      <item>
         <title>DJ Z-Trip Mixtape for Obama</title>
         <link>http://nate.koechley.com/blog/2008/10/10/dj-z-trip-mixtape-for-obama/</link>
         <description>DJ Z-Trip (with designer Shepard Fairey) has thrown some fundraisers for the Obama campaign called the &amp;#8220;The Party for Change.&amp;#8221; A few days ago he made the 54 minute set available as a free mp3 download. You can read more about it and grab it on his site, or save him a bit of bandwidth [...]</description>
         <guid isPermaLink="false">http://nate.koechley.com/blog/?p=507</guid>
         <pubDate>Fri, 10 Oct 2008 14:49:33 -0700</pubDate>
         <content:encoded><![CDATA[<p><a rel="nofollow" target="_blank" href="http://en.wikipedia.org/wiki/DJ_Z-Trip">DJ Z-Trip</a> (with designer Shepard Fairey) has thrown some fundraisers for the Obama campaign called the &#8220;The Party for Change.&#8221; A few days ago he made the 54 minute set available as a free mp3 download. </p>
<p>You can read more about it and <a rel="nofollow" target="_blank" href="http://www.djztrip.com/obama/">grab it on his site</a>, or save him a bit of bandwidth and <a rel="nofollow" target="_blank" href="http://nate.koechley.com/music/Z-Trip_ObamaMix.zip">grab it from me (.zip, 85mb)</a>. (It&#8217;s public domain and he encourages its wide distribution!)</p>
<p>Here&#8217;s a great DJ with a great ear and premier turntable skills that pulls music from across genres. This mix is no exception. </p>
<p>I agree with his signoff:</p>
<blockquote><p>I honestly feel if we make our voices heard, this time WILL be different.</p></blockquote>]]></content:encoded>
      </item>
      <item>
         <title>Finances: Avoid Rash Moves</title>
         <link>http://nate.koechley.com/blog/2008/10/10/avoid-rash-financial-oves/</link>
         <description>The New York Times has a story up today called Switching to Cash May Feel Safe, but Risks Remain. I highly recommend that you read it.
I&amp;#8217;m not a particularly savvy financial person, but &amp;#8220;think long term&amp;#8221; always struck me as wise. There&amp;#8217;s no doubt that it&amp;#8217;s pretty hairy out there right now, but I think [...]</description>
         <guid isPermaLink="false">http://nate.koechley.com/blog/?p=506</guid>
         <pubDate>Fri, 10 Oct 2008 10:27:08 -0700</pubDate>
         <content:encoded><![CDATA[<p>The New York Times has a story up today called <a rel="nofollow" target="_blank" href="http://www.nytimes.com/2008/10/09/business/yourmoney/09money.html?em">Switching to Cash May Feel Safe, but Risks Remain</a>. I highly recommend that you read it.</p>
<p>I&#8217;m not a particularly savvy financial person, but &#8220;think long term&#8221; always struck me as wise. There&#8217;s no doubt that it&#8217;s pretty hairy out there right now, but I think changing course or being overly emotion is the worst reaction. It&#8217;s tempting to be emotional and run for cover, but this article cites research that should give you strength and resolve.</p>
<p>As the title says, switching to cash may fell safe. But:</p>
<blockquote><p>But if you sell now, you’ll be locking in your losses. And once you’re in cash, there isn’t much upside. In fact, with interest rates low, you’re likely to lose money in cash, because inflation will probably eat up the after-tax returns you earn from a savings or money-market account.</p></blockquote>
<p>Beyond the low upside of cash, selling low is, obviously, the worst time to sell. It&#8217;s bad because you lock in your losses, <strong>but the read damage is that you&#8217;ll miss the eventual upswing, to devastating effect</strong>. </p>
<p>The research they cite is pretty amazing (emphasis mine):</p>
<blockquote><p>From 1963 to 2004, the index of American stocks he tested gained 10.84 percent annually in a geometric average, which avoided overstating the true performance. For people who missed the 90 biggest-gaining days in that period, however, the annual return fell to just 3.2 percent. <strong>Less than 1 percent of the trading days accounted for 96 percent of the market gains.</strong></p>
<p>&#8230;</p>
<p><strong>A portfolio belonging to an investor who missed the 10 best days over several decades across all of those markets would end up, on average, with about half the balance of someone who sat tight throughout.</strong></p></blockquote>
<p>They note that if you need the money in the next five years &#8212; if you&#8217;re about to retire &#8212; then perhaps the loss of the move to cash might make sense. But for me, and for many of you, &#8220;today’s price is not your price. Your price is 10 or 20 years from now.&#8221;</p>
<p>So, hang on to what you&#8217;ve got and don&#8217;t make any rash moves. </p>]]></content:encoded>
      </item>
      <item>
         <title>Accessibility Movers – Henny Swan to Opera from RNIB</title>
         <link>http://nate.koechley.com/blog/2008/09/09/henny-iheni-swan/</link>
         <description>I just noticed that Henry Henny &amp;#8220;iheni&amp;#8221; Swan &amp;#8212; Senior Web Accessibility Consultant at Royal National Institute of the Blind for the past six years &amp;#8212; is taking a job at Opera Software as a Web Evangelist. In addition to wishing him her well, his her post, Hello Opera provides a few quick tidbits about [...]</description>
         <guid isPermaLink="false">http://nate.koechley.com/blog/?p=504</guid>
         <pubDate>Tue, 09 Sep 2008 05:44:50 -0700</pubDate>
         <content:encoded><![CDATA[<p>I just noticed that <strike>Henry</strike> Henny &#8220;iheni&#8221; Swan &#8212; Senior Web Accessibility Consultant at Royal National Institute of the Blind for the past six years &#8212; is taking a job at Opera Software as a Web Evangelist. In addition to wishing <strike>him</strike> her well, <strike>his</strike> her post, <a rel="nofollow" target="_blank" href="http://www.iheni.com/hello-opera/">Hello Opera</a> provides a few quick tidbits about the Opera roster these days.</p>
<p>Congrats, iheni! I hope to see at a conference soon.</p>
<p> Update: I wrote this post in the middle of the night after working entirely too long and late. In my delirium, I misread Henny as Henry and used incorrect pronouns. Further, in the headline I mistakenly typed Swar instead of Swan (though I got it right in the body and in the permalink). </p>
<p>Sincere apologies for my clumsiness. Thanks to Henny for setting me straight!</p>]]></content:encoded>
      </item>
      <item>
         <title>Wireframing with Balsamiq Mockups</title>
         <link>http://nate.koechley.com/blog/2008/09/09/wireframing-with-balsamiq-mockup/</link>
         <description>Thanks to Pras for the pointer to Balsamiq&amp;#8217;s Mockups application. I was sketching wireframes quickly within minutes of finding the product. I believe in low-fidelity sketching at the wireframe stage. Balsamiq makes it easy with its large library of UI control stencils, its auto-complete driven keybroad stencil selection, on-screen snap-to alignment guides, a powerful inspector [...]</description>
         <guid isPermaLink="false">http://nate.koechley.com/blog/?p=503</guid>
         <pubDate>Tue, 09 Sep 2008 03:17:38 -0700</pubDate>
         <content:encoded><![CDATA[<p>Thanks to <a rel="nofollow" target="_blank" href="http://twitter.com/prasnation/statuses/914814003">Pras</a> for the pointer to <a rel="nofollow" target="_blank" href="http://www.balsamiq.com/products/mockups/tour">Balsamiq&#8217;s Mockups</a> application. I was sketching wireframes quickly within minutes of finding the product. </p>
<p>I believe in low-fidelity sketching at the wireframe stage. Balsamiq makes it easy with its large library of UI control stencils, its auto-complete driven keybroad stencil selection, on-screen snap-to alignment guides, a powerful inspector for precise control when rarely needed, and, more of all, a simplicity that makes it easy to start sketching or tweaking your mockup immediately. </p>
<p>The output is Balsamiq files, PGN or flattened image files, and XML. Because it exports XML it&#8217;s possible to use Balsamiq as a programmatic ingredient for downstream engineering systems and tools (such as partially automating the creation of detailed functional specifications, or using it as source for the automated building on the actual interface. </p>
<p>There is a rumor that they&#8217;ll be announcing clickable output files shortly, which might allow for the fast creation of clickable wireframes for usability testing (and other) needs.</p>
<p>I haven&#8217;t noticed, but it should be possible to customize what&#8217;s in the included UI Widget Library to a) take on a different visual skin; b) reflect new or fewer interface widget options.</p>
<p>All and all, I&#8217;m pretty intrigued. It seems there&#8217;s a market for consumer-friendly ways to design interfaces. Once more people catch on how to much fun we&#8217;re having, they&#8217;ll want a shot at designing and realizing all the apps they&#8217;re dreaming up, too!</p>
<p>I&#8217;d love to hear what you think of this approach. Have you tried it? Does it work for your teams&#8221;</p>
<p><a rel="nofollow" target="_blank" href="http://www.flickr.com/photos/natekoechley/2842824750/" title="Balsamiq Mockups For Desktop - * New Mockup by natekoechley, on Flickr"><img src="http://farm4.static.flickr.com/3130/2842824750_8f8680f49e_m.jpg" width="240" height="218" alt="Balsamiq Mockups For Desktop - * New Mockup"/></a></p>]]></content:encoded>
      </item>
      <item>
         <title>Large Hadron Collider (LHC) Rap</title>
         <link>http://nate.koechley.com/blog/2008/09/09/large-hadron-collider-lhc-rap/</link>
         <description>Here&amp;#8217;s a pointer to a scientifically accurate rap about the Large Hadron Collider (LHC). Story on www.telegraph.co.uk &amp;#8211; YouTube permalink.
From the story:
Now a larky but accurate rap song explaining the point of the 17 mile circumference machine [under Switzerland and France], which formally starts up on September 10, has made a star of Kate McAlpine, [...]</description>
         <guid isPermaLink="false">http://nate.koechley.com/blog/?p=502</guid>
         <pubDate>Tue, 09 Sep 2008 02:35:36 -0700</pubDate>
         <content:encoded><![CDATA[<p>Here&#8217;s a pointer to a scientifically accurate rap about the Large Hadron Collider (LHC). </p>
<p><a rel="nofollow" target="_blank" href="http://www.telegraph.co.uk/earth/main.jhtml?view=DETAILS&#038;grid=&#038;xml=/earth/2008/08/26/scirap126.xml">Story on www.telegraph.co.uk</a> &#8211; <a rel="nofollow" target="_blank" href="http://www.youtube.com/watch?v=j50ZssEojtM">YouTube permalink</a>.</p>
<p>From the story:</p>
<blockquote><p>Now a larky but accurate rap song explaining the point of the 17 mile circumference machine [under Switzerland and France], which formally starts up on September 10, has made a star of Kate McAlpine, 23, aka &#8220;alpinekat&#8221;, who stars with her friends in a YouTube video that has been downloaded more than [was 400,000 times when the article was published, and nearly 1.4mm now.]</p></blockquote>
<p>I liked watching the video. I&#8217;ve heard about the LHC before, but this 4 minutes taught me new facts about both the collide *and* its science. And there&#8217;s funny dancing.</p>
<p><iframe class="embeddedvideo" src="http://www.youtube.com/v/j50ZssEojtM&#038;hl=en&#038;fs=1" type="application/x-shockwave-flash" width="425" height="344"></iframe></p>]]></content:encoded>
      </item>
      <item>
         <title>Songbird Public Beta (0.7)</title>
         <link>http://nate.koechley.com/blog/2008/08/21/songbird-public-beta-07/</link>
         <description>Congrats to my buddies (yo Koshi!) over at Songbird for reaching another big milestone: public beta.
Songbird is a media player like iTunes. Except that it&amp;#8217;s build on top of the awesome Mozilla Firefox foundation. And like Firefox, it has an extensive array of extensions, themes, and assorted addons. Earlier versions haven&amp;#8217;t supplanted iTunes for me, [...]</description>
         <guid isPermaLink="false">http://nate.koechley.com/blog/?p=501</guid>
         <pubDate>Thu, 21 Aug 2008 12:08:06 -0700</pubDate>
         <content:encoded><![CDATA[<p>Congrats to my buddies (yo Koshi!) over at Songbird for reaching another big milestone: public beta.</p>
<p>Songbird is a media player like iTunes. Except that it&#8217;s build on top of the awesome Mozilla Firefox foundation. And like Firefox, it has an extensive array of extensions, themes, and assorted addons. Earlier versions haven&#8217;t supplanted iTunes for me, but it&#8217;s looking like this version may well do that.</p>
<p>I had some trouble imagining what type of addons would make sense, but in this release we&#8217;re beginning to see. An early favorite for me is the ticketing integration:</p>
<p><img src="http://nate.koechley.com/screencaps/Songbird_Blog_%C2%BB_Play_music._Play_the_Web.-20080821-120321.png" alt="Songbird%20Blog%20%C2%BB%20Play%20music.%20Play%20the%20Web."/></p>
<p>You can <a rel="nofollow" target="_blank" href="http://blog.songbirdnest.com/2008/08/20/songbird-beta-is-released/">read all about the release</a> on their blog, <a rel="nofollow" target="_blank" href="http://getsongbird.com/">download it here</a>, and see a screenshot below:</p>
<p><img src="http://nate.koechley.com/screencaps/Songbird-20080821-115530.png" alt="Songbird"/></p>]]></content:encoded>
      </item>
      <item>
         <title>Twitter Faster than Reality</title>
         <link>http://nate.koechley.com/blog/2008/07/29/twitter-faster-than-reality/</link>
         <description>LA shook at 11:42:15 today according to the official record from the U.S. Geological Survey. But according to [a report of] Twitter activity today (by the tweetip site) it happened 43 seconds earlier at 11:41:32 (adjusted for time zone). (graphic snagged from tweetip site)
That Twitter routinely breaks news fastest is often discussed, notably in the [...]</description>
         <guid isPermaLink="false">http://nate.koechley.com/blog/?p=500</guid>
         <pubDate>Tue, 29 Jul 2008 18:56:02 -0700</pubDate>
         <content:encoded><![CDATA[<p>LA shook at 11:42:15 today according to <a rel="nofollow" target="_blank" href="http://pasadena.wr.usgs.gov/shake/ca/STORE/X14383980/ciim_display.html">the official record</a> from the U.S. Geological Survey. But according to [a report of] Twitter activity today (<a rel="nofollow" target="_blank" href="http://tweetip.tumblr.com/post/43980447/earthquake-s-california-timeline-listing-of-1st">by the tweetip site</a>) it happened 43 seconds earlier at 11:41:32 (adjusted for time zone). </p>
<p><a rel="nofollow" target="_blank" href="http://tweetip.tumblr.com/post/43980447/earthquake-s-california-timeline-listing-of-1st"><img src="http://nate.koechley.com/screencaps/tweetip-20080729-182303.png" alt="tweetip"/></a></p>
<p>(graphic snagged from tweetip site)</p>
<p>That Twitter routinely breaks news fastest is often <a rel="nofollow" target="_blank" href="http://venturebeat.com/2008/05/12/twitter-is-first-on-the-scene-for-a-major-earthquake-but-who-cares-about-that-is-it-mainstream-yet/">discussed</a>, notably in the wake of the May quake in China. </p>
<p>Today the AP&#8217;s wire posted news of the earthquake 9 minutes after it happened. 9 minutes is fast. Negative :43 is amazing.</p>
<p>(Yeah, yeah. I know. It&#8217;s explainable as an accounting error in twitter&#8217;s api or tweetip&#8217;s processing. But the point remains that twitter is always on the scene.)</p>]]></content:encoded>
      </item>
      <item>
         <title>Links for 2009-11-27 [del.icio.us]</title>
         <link>http://feedproxy.google.com/~r/mattmcalister/~3/BlPs7YfAMjU/mattmcalister</link>
         <description>&lt;ul&gt;
&lt;li&gt;&lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://www.danah.org/papers/talks/Web2Expo.html&quot;&gt;&quot;Streams of Content, Limited Attention: The Flow of Information through Social Media&quot;&lt;/a&gt;&lt;br/&gt;
For the longest time, we have focused on sites of information as a destination, of accessing information as a process, of producing information as a task. What happens when all of this changes?&lt;/li&gt;
&lt;/ul&gt;&lt;img src=&quot;http://feeds.feedburner.com/~r/mattmcalister/~4/BlPs7YfAMjU&quot; height=&quot;1&quot; width=&quot;1&quot;/&gt;</description>
         <guid isPermaLink="false">http://del.icio.us/mattmcalister#2009-11-27</guid>
         <pubDate>Sat, 28 Nov 2009 00:00:00 -0800</pubDate>
      </item>
      <item>
         <title>Links for 2009-11-26 [del.icio.us]</title>
         <link>http://feedproxy.google.com/~r/mattmcalister/~3/F6yr21bqzWM/mattmcalister</link>
         <description>&lt;ul&gt;
&lt;li&gt;&lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://ondemandmedia.typepad.com/odm/2009/11/publishing-aggregation-and-disruption.html&quot;&gt;On-demand Media: Publishing, aggregation and &amp;ldquo;The Innovator&amp;rsquo;s Dilemma&amp;rdquo;&lt;/a&gt;&lt;br/&gt;
examine the market data, study the demographics, lifestyles, challenges and habits of potential readers and then bring together editorial, advertising, technology and marketing to create digital products that serve users and advertisers and do so profitably.&lt;/li&gt;
&lt;/ul&gt;&lt;img src=&quot;http://feeds.feedburner.com/~r/mattmcalister/~4/F6yr21bqzWM&quot; height=&quot;1&quot; width=&quot;1&quot;/&gt;</description>
         <guid isPermaLink="false">http://del.icio.us/mattmcalister#2009-11-26</guid>
         <pubDate>Fri, 27 Nov 2009 00:00:00 -0800</pubDate>
      </item>
      <item>
         <title>Socially linked data</title>
         <link>http://feedproxy.google.com/~r/mattmcalister/~3/0FwyJoMh_wA/</link>
         <description>The semantic web folks, including Sir Tim Berners-Lee, have been saying for years that the Internet could become significantly more compelling by cooking more intelligence into the way things link around the network. The movement is getting some legs to it these days, but the solution doesn&amp;#8217;t look quite like what the visionaries expected [...]</description>
         <guid isPermaLink="false">http://www.mattmcalister.com/blog/?p=508</guid>
         <pubDate>Thu, 26 Nov 2009 02:46:31 -0800</pubDate>
         <content:encoded/>
         <enclosure length="419608" url="http://video.ted.com/assets/player/swf/EmbedPlayer.swf" type="application/x-shockwave-flash"/>
      </item>
      <item>
         <title>Positioning real-time web platforms</title>
         <link>http://feedproxy.google.com/~r/mattmcalister/~3/IDu3glmlq0U/</link>
         <description>Like many people, I&amp;#8217;ve been thinking a lot about the live nature of the web more and more recently. The startup world has gone mad for it. And though I think Microsoft&amp;#8217;s Chief Software Architect Ray Ozzie played down the depth of Microsoft&amp;#8217;s commitment to it in his recent interview with Steve Gillmor, [...]</description>
         <guid isPermaLink="false">http://www.mattmcalister.com/blog/?p=488</guid>
         <pubDate>Thu, 26 Nov 2009 02:48:50 -0800</pubDate>
         <content:encoded/>
      </item>
      <item>
         <title>Links for 2009-11-25 [del.icio.us]</title>
         <link>http://feedproxy.google.com/~r/mattmcalister/~3/RlgF0TUp2os/mattmcalister</link>
         <description>&lt;ul&gt;
&lt;li&gt;&lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://www.zephoria.org/thoughts/&quot;&gt;apophenia: spectacle at Web2.0 Expo... from my perspective&lt;/a&gt;&lt;br/&gt;
The problem with a public-facing Twitter stream in events like this is that it FORCES the audience to pay attention the backchannel. So even audience members who want to focus on the content get distracted.&lt;/li&gt;
&lt;li&gt;&lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://www.slideshare.net/jdlasica/the-new-journalist-in-the-age-of-social-media?src=embed&quot;&gt;The New Journalist in the Age of Social Media&lt;/a&gt;&lt;br/&gt;
An audience will watch you fall on a sword. A community will fall on a sword for you.&lt;/li&gt;
&lt;li&gt;&lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://flowingdata.com/2009/11/25/9-ways-to-visualize-proportions-a-guide/&quot;&gt;9 Ways to Visualize Proportions &amp;ndash; A Guide | FlowingData&lt;/a&gt;&lt;br/&gt;
With all the visualization options out there, it can be hard to figure out what graph or chart suits your data best. This is a guide to make your decision easier for one particular type of data: proportions.&lt;/li&gt;
&lt;/ul&gt;&lt;img src=&quot;http://feeds.feedburner.com/~r/mattmcalister/~4/RlgF0TUp2os&quot; height=&quot;1&quot; width=&quot;1&quot;/&gt;</description>
         <guid isPermaLink="false">http://del.icio.us/mattmcalister#2009-11-25</guid>
         <pubDate>Thu, 26 Nov 2009 00:00:00 -0800</pubDate>
      </item>
      <item>
         <title>Links for 2009-11-24 [del.icio.us]</title>
         <link>http://feedproxy.google.com/~r/mattmcalister/~3/yegMKmPKERI/mattmcalister</link>
         <description>&lt;ul&gt;
&lt;li&gt;&lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://paidcontent.org/article/419-vogue-turns-to-obamas-online-fundraiser-for-revenue-drive/&quot;&gt;Vogue Turns To Obama&amp;rsquo;s Online Fundraiser For Revenue Drive | paidContent&lt;/a&gt;&lt;br/&gt;
A big part of what Vogue wants to learn is whether there are enough people out there willing to pay for the magazine’s online content. But executives think they’ll learn more than that for its revenue drive, such as how to market its e-commerce and subscription marketing initiatives.&lt;/li&gt;
&lt;/ul&gt;&lt;img src=&quot;http://feeds.feedburner.com/~r/mattmcalister/~4/yegMKmPKERI&quot; height=&quot;1&quot; width=&quot;1&quot;/&gt;</description>
         <guid isPermaLink="false">http://del.icio.us/mattmcalister#2009-11-24</guid>
         <pubDate>Wed, 25 Nov 2009 00:00:00 -0800</pubDate>
      </item>
      <item>
         <title>Links for 2009-11-19 [del.icio.us]</title>
         <link>http://feedproxy.google.com/~r/mattmcalister/~3/Z7D9YxvqXuo/mattmcalister</link>
         <description>&lt;ul&gt;
&lt;li&gt;&lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://www.observer.com/2009/media/dash-dc-tech-guru-will-head-govt-incubator-digitize-democracy&quot;&gt;Dash to D.C.! Tech Guru Will Head Gov't Incubator, Digitize Democracy | The New York Observer&lt;/a&gt;&lt;br/&gt;
“The current administration is comprised in great part of digital natives. The government is already using technology to talk to citizens, but we’re going to make technology that helps government listen to them.”&lt;/li&gt;
&lt;/ul&gt;&lt;img src=&quot;http://feeds.feedburner.com/~r/mattmcalister/~4/Z7D9YxvqXuo&quot; height=&quot;1&quot; width=&quot;1&quot;/&gt;</description>
         <guid isPermaLink="false">http://del.icio.us/mattmcalister#2009-11-19</guid>
         <pubDate>Fri, 20 Nov 2009 00:00:00 -0800</pubDate>
      </item>
      <item>
         <title>Links for 2009-11-17 [del.icio.us]</title>
         <link>http://feedproxy.google.com/~r/mattmcalister/~3/Yk62JUs78-8/mattmcalister</link>
         <description>&lt;ul&gt;
&lt;li&gt;&lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://www.avc.com/a_vc/2009/11/apis-in-the-late-afternoon.html&quot;&gt;APIs In The Late Afternoon&lt;/a&gt;&lt;br/&gt;
the best way to monetize apis is to send money with the api. Paul Forster, CEO of Indeed: &quot;We tried charging for our API without much success. Then we paid developers to use it and it took off.&quot;&lt;/li&gt;
&lt;/ul&gt;&lt;img src=&quot;http://feeds.feedburner.com/~r/mattmcalister/~4/Yk62JUs78-8&quot; height=&quot;1&quot; width=&quot;1&quot;/&gt;</description>
         <guid isPermaLink="false">http://del.icio.us/mattmcalister#2009-11-17</guid>
         <pubDate>Wed, 18 Nov 2009 00:00:00 -0800</pubDate>
      </item>
      <item>
         <title>Links for 2009-11-16 [del.icio.us]</title>
         <link>http://feedproxy.google.com/~r/mattmcalister/~3/LqyewAMWK70/mattmcalister</link>
         <description>&lt;ul&gt;
&lt;li&gt;&lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://blogs.law.harvard.edu/vrm/2009/11/16/advertising-in-reverse/&quot;&gt;Advertising in Reverse&lt;/a&gt;&lt;br/&gt;
Any of us should be able to broadcast, in a secure and selective way that protects our privacies, specified goods we’re shopping for.&lt;/li&gt;
&lt;/ul&gt;&lt;img src=&quot;http://feeds.feedburner.com/~r/mattmcalister/~4/LqyewAMWK70&quot; height=&quot;1&quot; width=&quot;1&quot;/&gt;</description>
         <guid isPermaLink="false">http://del.icio.us/mattmcalister#2009-11-16</guid>
         <pubDate>Tue, 17 Nov 2009 00:00:00 -0800</pubDate>
      </item>
      <item>
         <title>The thinking behind the Activate Summit event</title>
         <link>http://feedproxy.google.com/~r/mattmcalister/~3/11FBYfqiuWU/</link>
         <description>The premise that the Internet is changing everything is only more potent now than it was when many people first considered that it might be true. Today we&amp;#8217;re seeing how its capabilities have found their way into the hands of those who are actively changing the world.
But the key questions haven&amp;#8217;t yet been played [...]</description>
         <guid isPermaLink="false">http://www.mattmcalister.com/blog/?p=421</guid>
         <pubDate>Thu, 04 Jun 2009 02:32:26 -0700</pubDate>
         <content:encoded/>
      </item>
      <item>
         <title>The cost of transparency and accountability</title>
         <link>http://feedproxy.google.com/~r/mattmcalister/~3/Mifldzs2Rjc/</link>
         <description>The MP Expenses issue is a very interesting story. There are lots of reasons why it is spreading so aggressively&amp;#8230; in hard times people look for someone to blame for what&amp;#8217;s wrong in the world
people are learning to expect more transparency from their government
the availability of the data compells the curious to dive into all [...]</description>
         <guid isPermaLink="false">http://www.mattmcalister.com/blog/?p=397</guid>
         <pubDate>Tue, 12 May 2009 03:50:43 -0700</pubDate>
         <content:encoded/>
      </item>
      <item>
         <title>Response to the Open Platform launch</title>
         <link>http://feedproxy.google.com/~r/mattmcalister/~3/h9pc3_rANmM/</link>
         <description>The Open Platform launch earlier this month was one of the more exciting days I&amp;#8217;ve had in a long time. We&amp;#8217;ve done a good thing at the Guardian, and it seems we&amp;#8217;re not alone in thinking that.
Here are some of my favorite Twitter posts about the launch (more here): @IanYorston &amp;#8220;Guardian Open Platform may be [...]</description>
         <guid isPermaLink="false">http://www.mattmcalister.com/blog/?p=367</guid>
         <pubDate>Tue, 24 Mar 2009 06:47:50 -0700</pubDate>
         <content:encoded/>
         <enclosure length="121520" url="http://static.slideshare.net/swf/ssplayer2.swf?doc=changingmedia-march09-v2-090324055506-phpapp01&amp;#038;stripped_title=the-open-strategy" type="application/x-shockwave-flash"/>
      </item>
      <item>
         <title>A few interesting data projects</title>
         <link>http://feedproxy.google.com/~r/mattmcalister/~3/Xg5XTcDjsJo/</link>
         <description>The contagious data bug must be sweeping through the office, as several very different but very interesting data-driven publishing projects rolled out almost simultaneously.
First, infographics editor Paddy Allen explains the global recession through a very elegant interactive piece &amp;#8220;Where did all the money go?&amp;#8220;. Paddy has quite a collection of brilliant work from his [...]</description>
         <guid isPermaLink="false">http://www.mattmcalister.com/blog/?p=357</guid>
         <pubDate>Mon, 02 Feb 2009 05:39:56 -0800</pubDate>
         <content:encoded/>
         <enclosure length="171060" url="http://www.guardianchalkboards.com/guardianchalkboards_embed.swf?chalkBoardID=4Fje716WB895eeRE0h10" type="application/x-shockwave-flash"/>
      </item>
      <item>
         <title>Building communities from Twitter posts</title>
         <link>http://feedproxy.google.com/~r/mattmcalister/~3/N-lxhrnY8ic/</link>
         <description>I spent a little time over the last couple of weeks playing around with some Twitter data. I was noticing how several people, myself included, were sharing the funny things their kids say sometimes: &amp;#8220;it is noisy outside. my daughter said, &amp;#8216;the texans are shooting their guns!&amp;#8217; no, dear. just fireworks&amp;#8220;
&amp;#8220;Asked my son to hold [...]</description>
         <guid isPermaLink="false">http://www.mattmcalister.com/blog/?p=304</guid>
         <pubDate>Sat, 03 Jan 2009 12:54:38 -0800</pubDate>
         <content:encoded/>
         <enclosure length="14271" url="http://search.twitter.com/search.atom?q=daughter+said" type="application/atom+xml; charset=utf-8"/>
      </item>
      <item>
         <title>Breaking through the attention barrier</title>
         <link>http://feedproxy.google.com/~r/mattmcalister/~3/pQIEtm5-37I/</link>
         <description>For some reason I get a bit annoyed when people write about our information overload limits. This happened the other day when I saw Seth Godin&amp;#8217;s piece titled &amp;#8220;Warning: The internet is almost full.&amp;#8221; He writes:
&amp;#8220;The decentralized nature of the net means that it will never be physically full. As long as we [...]</description>
         <guid isPermaLink="false">http://www.mattmcalister.com/blog/?p=271</guid>
         <pubDate>Sun, 14 Dec 2008 13:58:11 -0800</pubDate>
         <content:encoded/>
      </item>
      <item>
         <title>Hacking BNP data</title>
         <link>http://feedproxy.google.com/~r/mattmcalister/~3/_Cw7q43_-7k/</link>
         <description>Less than a week after trying out some new data mapping concepts at Guardian Hack Day, a big pile of data appeared on the Internet begging to be mapped. Using some of their new skills and a convenient constituency data tool, a small team of innovators got to work to produce some really interesting [...]</description>
         <guid isPermaLink="false">http://www.mattmcalister.com/blog/?p=262</guid>
         <pubDate>Fri, 21 Nov 2008 15:42:47 -0800</pubDate>
         <content:encoded/>
         <category>All</category>
      </item>
      <item>
         <title>Notes from Hack Day at The Guardian</title>
         <link>http://feedproxy.google.com/~r/mattmcalister/~3/NpR5MrNyJ68/</link>
         <description>We hosted our first Hack Day last week at The Guardian. Amazing fun. Here&amp;#8217;s a 15min highlight reel: We did a lot of the standard stuff that makes Hack Day so interesting, but there were a few innovations to the event format itself that I thought worked really well, too: DabbleDB. Simon Willison setup [...]</description>
         <guid isPermaLink="false">http://www.mattmcalister.com/blog/?p=256</guid>
         <pubDate>Tue, 18 Nov 2008 10:59:05 -0800</pubDate>
         <content:encoded/>
         <enclosure length="-1" url="http://vimeo.com/moogaloop.swf?clip_id=2276648&amp;server=vimeo.com&amp;show_title=1&amp;show_byline=1&amp;show_portrait=0&amp;color=00ADEF&amp;fullscreen=1" type="application/x-shockwave-flash"/>
      </item>
      <item>
         <title>Python-YQL: client library for YQL</title>
         <link>http://muffinresearch.co.uk/archives/2009/11/24/python-yql-client-library-for-yql/</link>
         <description>You&amp;#8217;d of have to have been under a rock to not have heard about Yahoo Query Language which provides a &amp;#8220;SQL-like&amp;#8221; abstraction to Yahoo&amp;#8217;s own APIs as well as a growing number of third party APIs. I&amp;#8217;ll be honest; for a while I was quite dismissive of YQL thinking that if I was using those [...]</description>
         <guid isPermaLink="false">http://muffinresearch.co.uk/?p=769</guid>
         <pubDate>Tue, 24 Nov 2009 13:52:18 -0800</pubDate>
         <content:encoded><![CDATA[<p>You&#8217;d of have to have been under a rock to not have heard about <a rel="nofollow" target="_blank" href="http://developer.yahoo.com/yql/">Yahoo Query Language</a> which provides a &#8220;SQL-like&#8221; abstraction to Yahoo&#8217;s own APIs as well as a growing number of third party APIs. </p>
<p>I&#8217;ll be honest; for a while I was quite dismissive of YQL thinking that if I was using those APIs then I&#8217;d query them directly rather than use a 3rd party abstraction. But then I saw a recent post from <a rel="nofollow" target="_blank" href="http://www.wait-till-i.com">Christian Heilmann</a> that touched on making YQL calls from the server that began to pique my interest. It made me start to think about all the data from the web that could be accessed from just some simple SQL-like queries.</p>
<p>So I decided in order to try out YQL I&#8217;d build a dedicated client library. This also provided me with an opportunity to explore OAuth properly as I&#8217;d need to make the client work with both Two and ThreeLegged Oauth so it&#8217;s also relatively straightforward to query Private tables from a web application.</p>
<p>The result is Python-YQL which you can install from PyPi with:</p>
<pre><code>sudo easy_install yql</code></pre>
<p>The documentation is available at <a rel="nofollow" target="_blank" href="http://python-yql.org/">http://python-yql.org/</a> and branches are available at <a rel="nofollow" target="_blank" href="https://launchpad.net/python-yql/">Launchpad.net</a> or you can get a branch with the following:</p>
<pre><code>bzr branch lp:python-yql</code></pre>
<p>Basic usage is along the following lines:</p>
<pre><code>&gt;&gt;&gt; import yql
&gt;&gt;&gt; y = yql.Public()
&gt;&gt;&gt; query = 'select * from flickr.photos.search where text="panda" limit 3';
&gt;&gt;&gt; y.execute(query)</code></pre>
<p>For details on more advanced usage see the docs at <a rel="nofollow" target="_blank" href="http://python-yql.org/">python-yql.org</a></p>
<h3>Patches Welcome!</h3>
<p>So go and check it out and kick the proverbial tyres. It&#8217;s early days and there&#8217;s bound to be some bugs and missing features but this is where you come in. I&#8217;ll happily expedite provision of fixes as they come in. Patches/Bug reports/branches are welcome!</p>
<h3>Python Oauth2</h3>
<p>For oauth integration, I started out using python-oauth until <a rel="nofollow" target="_blank" href="http://cyril.doussin.name/">Cyril</a> mentioned that Joe Stump had created a new oauth library based on various forks of the original python-oauth. <a rel="nofollow" target="_blank" href="http://github.com/simplegeo/python-oauth2">Python-oauth2</a> provides an easy to use well-tested library that is a natural progression of python-oauth.</p>
<p>Once I knew about it I couldn&#8217;t resist switching python-yql over to using it. At the moment I&#8217;m bundling python-oauth2 as I needed to patch in support to to make it work with python versions &lt; 2.6. However hopefully in due course this will cease to be necessary.</p>
<h3>Future</h3>
<p>There&#8217;s lots I can improve upon but for now I&#8217;m planning to spend some time using the library in order to work out what can be better. <del datetime="2009-11-25T23:12:20+00:00">I&#8217;m thinking one of the first things I&#8217;d like to do is make what&#8217;s returned an object rather than just simply returning the data. This will mean that I can provide useful attributes such as the query that was called to return that dataset for example.</del> This is now a reality. </p> 
<p>The version in the trunk branch now returns a YQL object which provides a much more awesome API for accessing the data returned by YQL queries. This will be released as 0.3 and at that point I&#8217;ll update the docs. Until then here&#8217;s a taster:</p>
<pre><code>&gt;&gt;&gt; import yql
&gt;&gt;&gt; y = yql.Public()
&gt;&gt;&gt; res = y.execute("use 'http://yqlblog.net/samples/search.imageweb.xml' as searchimageweb; select title from searchimageweb where query='pizza' limit 3")
&gt;&gt;&gt; print res
&lt;yql.YQL object at 0xb77adc2c&gt;
&gt;&gt;&gt; res.rows
[{u'title': u'&lt;b&gt;Pizza&lt;/b&gt; Hut'}, {u'title': u"Domino's &lt;b&gt;Pizza&lt;/b&gt; -
Official Site"}, {u'title': u"Papa John's"}]
&gt;&gt;&gt; res.rows[0]
{u'title': u'&lt;b&gt;Pizza&lt;/b&gt; Hut'}
&gt;&gt;&gt; res.rows[1]
{u'title': u"Domino's &lt;b&gt;Pizza&lt;/b&gt; - Official Site"}
&gt;&gt;&gt; res.query
u"use 'http://yqlblog.net/samples/search.imageweb.xml' as searchimageweb; select title from searchimageweb where query='pizza' limit 3"
&gt;&gt;&gt; res.uri
u'http://query.yahooapis.com/v1/yql?q=use+%27http%3A%2F%2Fyqlblog.net%2Fsamples%2Fsearch.imageweb.xml%27+as+searchimageweb%3B+select+title+from+searchimageweb+where+query%3D%27pizza%27+limit+3'
&gt;&gt;&gt; res.count
3</code></pre>
<div class="feedflare">
<a rel="nofollow" target="_blank" href="http://feeds.feedburner.com/~ff/muffinres/skimmed?a=q5fvO9ukgCc:OK_FVPDYn2U:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/muffinres/skimmed?d=yIl2AUoC8zA" border="0"></a> <a rel="nofollow" target="_blank" href="http://feeds.feedburner.com/~ff/muffinres/skimmed?a=q5fvO9ukgCc:OK_FVPDYn2U:2nqncYFp4_M"><img src="http://feeds.feedburner.com/~ff/muffinres/skimmed?d=2nqncYFp4_M" border="0"></a> <a rel="nofollow" target="_blank" href="http://feeds.feedburner.com/~ff/muffinres/skimmed?a=q5fvO9ukgCc:OK_FVPDYn2U:7Q72WNTAKBA"><img src="http://feeds.feedburner.com/~ff/muffinres/skimmed?d=7Q72WNTAKBA" border="0"></a> <a rel="nofollow" target="_blank" href="http://feeds.feedburner.com/~ff/muffinres/skimmed?a=q5fvO9ukgCc:OK_FVPDYn2U:2mJPEYqXBVI"><img src="http://feeds.feedburner.com/~ff/muffinres/skimmed?d=2mJPEYqXBVI" border="0"></a>
</div>]]></content:encoded>
      </item>
      <item>
         <title>Spotify: Linking to a specific time in a track</title>
         <link>http://muffinresearch.co.uk/archives/2009/11/11/spotify-linking-to-a-specific-time-in-a-track/</link>
         <description>For a while I&amp;#8217;ve wanted to be able to share a link to a track on spotify so that it jumps the right place. An example is when learning covers for the band I play in; or just to point out a great part of the track.
The good new is that this is already possible! [...]</description>
         <guid isPermaLink="false">http://muffinresearch.co.uk/?p=757</guid>
         <pubDate>Wed, 11 Nov 2009 03:56:10 -0800</pubDate>
         <content:encoded><![CDATA[<p>For a while I&#8217;ve wanted to be able to share a link to a track on spotify so that it jumps the right place. An example is when learning covers for the band I play in; or just to point out a great part of the track.</p>
<p>The good new is that this is already possible! I asked a question on <a rel="nofollow" target="_blank" href="http://getsatisfaction.com/spotify/topics/allow_linking_to_a_point_into_a_track">Get Satisfaction</a> and a Spotify employee Emil Hesslow answered straight away that this feature already exists. Here&#8217;s some examples:</p>
<ul class="ext">
<li>Check out George Benson&#8217;s guitar break: <a rel="nofollow" target="_blank" href="http://open.spotify.com/track/39Bi2scq80BWdgnxz2llWT%2304%3A04">Uncle Albert/Admiral Halsey 4:04</a></li>
<li>A Nice hammond organ break from Greg Rolie: <a rel="nofollow" target="_blank" href="http://open.spotify.com/track/6s3pzloNKkO3dzZaHaKaoi%230%3A46">Toussaint L&#8217;Overture 0:46</a></li>
</ul>
<p>You can also use the spotify protocol:</p>
<p>e.g: <a rel="nofollow">spotify:track:39Bi2scq80BWdgnxz2llWT#04:04</a></p>
<p>The format for the link is just a simple fragment identifier added to the end of the link in the format #mins:secs e.g: #4:04</p>
<p>From using this (I&#8217;m running Spotify under wine) I&#8217;ve found you need to URLencode this in the &#8220;http://open.spotify&hellip;&#8221; links for it to work so #4:04 becomes %2304%3A04.</p>
<div class="feedflare">
<a rel="nofollow" target="_blank" href="http://feeds.feedburner.com/~ff/muffinres/skimmed?a=zEtHn01s0OI:nTcP5J0tXvk:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/muffinres/skimmed?d=yIl2AUoC8zA" border="0"></a> <a rel="nofollow" target="_blank" href="http://feeds.feedburner.com/~ff/muffinres/skimmed?a=zEtHn01s0OI:nTcP5J0tXvk:2nqncYFp4_M"><img src="http://feeds.feedburner.com/~ff/muffinres/skimmed?d=2nqncYFp4_M" border="0"></a> <a rel="nofollow" target="_blank" href="http://feeds.feedburner.com/~ff/muffinres/skimmed?a=zEtHn01s0OI:nTcP5J0tXvk:7Q72WNTAKBA"><img src="http://feeds.feedburner.com/~ff/muffinres/skimmed?d=7Q72WNTAKBA" border="0"></a> <a rel="nofollow" target="_blank" href="http://feeds.feedburner.com/~ff/muffinres/skimmed?a=zEtHn01s0OI:nTcP5J0tXvk:2mJPEYqXBVI"><img src="http://feeds.feedburner.com/~ff/muffinres/skimmed?d=2mJPEYqXBVI" border="0"></a>
</div>]]></content:encoded>
      </item>
      <item>
         <title>Web Application Security – LugRadio Live 2009</title>
         <link>http://muffinresearch.co.uk/archives/2009/11/01/web-application-security-lugradio-live-2009/</link>
         <description>These are my slides from the presentation I gave at LugRadio Live 2009 at Wolverhampton. The presentation was a brief tour of some common security issues you might come across developing web applications. I also covered ReDOS which is a lot less well known but an interesting vulnerability.
The notes are available on slideshare.net View more presentations [...]</description>
         <guid isPermaLink="false">http://muffinresearch.co.uk/?p=745</guid>
         <pubDate>Sun, 01 Nov 2009 03:04:32 -0800</pubDate>
         <content:encoded><![CDATA[<p>These are my slides from the presentation I gave at LugRadio Live 2009 at Wolverhampton. The presentation was a brief tour of some common security issues you might come across developing web applications. I also covered ReDOS which is a lot less well known but an interesting vulnerability.</p>
<p>The <a rel="nofollow" target="_blank" href="http://www.slideshare.net/muffinresearch/security-presentation-2437395">notes are available on slideshare.net</a></p>
<div style="width:425px;text-align:left;" id="__ss_2437395"><iframe class="embeddedvideo" src="http://static.slidesharecdn.com/swf/ssplayer2.swf?doc=security-presentation-091106061759-phpapp02&#038;stripped_title=security-presentation-2437395" type="application/x-shockwave-flash" width="425" height="355"></iframe> 
<div style="font-size:11px;font-family:tahoma, arial;height:26px;padding-top:2px;">View more <a rel="nofollow" style="text-decoration:underline;" target="_blank" href="http://www.slideshare.net/">presentations</a> from <a rel="nofollow" style="text-decoration:underline;" target="_blank" href="http://www.slideshare.net/muffinresearch">Stuart Colville</a>.</div>
</div>
<p><del datetime="2009-11-06T12:23:17+00:00">I&#8217;ve had to pull the presentation from slideshare.net temporarily &#8211; I&#8217;ll re-upload as soon as possible</del> The problem at slideshare has now been resolved.</p> 
<div class="feedflare">
<a rel="nofollow" target="_blank" href="http://feeds.feedburner.com/~ff/muffinres/skimmed?a=1n85StSPqPg:sV3FSoVF76g:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/muffinres/skimmed?d=yIl2AUoC8zA" border="0"></a> <a rel="nofollow" target="_blank" href="http://feeds.feedburner.com/~ff/muffinres/skimmed?a=1n85StSPqPg:sV3FSoVF76g:2nqncYFp4_M"><img src="http://feeds.feedburner.com/~ff/muffinres/skimmed?d=2nqncYFp4_M" border="0"></a> <a rel="nofollow" target="_blank" href="http://feeds.feedburner.com/~ff/muffinres/skimmed?a=1n85StSPqPg:sV3FSoVF76g:7Q72WNTAKBA"><img src="http://feeds.feedburner.com/~ff/muffinres/skimmed?d=7Q72WNTAKBA" border="0"></a> <a rel="nofollow" target="_blank" href="http://feeds.feedburner.com/~ff/muffinres/skimmed?a=1n85StSPqPg:sV3FSoVF76g:2mJPEYqXBVI"><img src="http://feeds.feedburner.com/~ff/muffinres/skimmed?d=2mJPEYqXBVI" border="0"></a>
</div>]]></content:encoded>
      </item>
      <item>
         <title>Ubuntu: Lock Screen and Pause Spotify</title>
         <link>http://muffinresearch.co.uk/archives/2009/10/22/ubuntu-lock-screen-and-pause-spotify/</link>
         <description>When I used a mac I had a shonky little applescript to pause iTunes when I locked the screen. These days I mostly listen to Spotify (running under wine) on Ubuntu which of course doesn&amp;#8217;t have applescript. What I wanted was a similar script so I can hit a keystroke and pause spotify and lock [...]</description>
         <guid isPermaLink="false">http://muffinresearch.co.uk/?p=719</guid>
         <pubDate>Thu, 22 Oct 2009 09:23:00 -0700</pubDate>
         <content:encoded><![CDATA[<p>When I used a mac I had a shonky little <a rel="nofollow" target="_blank" href="http://muffinresearch.co.uk/archives/2008/04/24/mac-tip-lock-screen-and-pause-itunes/">applescript to pause iTunes when I locked the screen</a>. </p>
<p>These days I mostly listen to Spotify (running under wine) on Ubuntu which of course doesn&#8217;t have applescript. What I wanted was a similar script so I can hit a keystroke and pause spotify and lock the screen at the same time.</p>
<p>With a few utilities I was able to programatically tell if Spotify is playing and get focus on the Spotify window and send a keystroke to get spotify to pause. But the solution it has to be said is far from perfect.</p>
<p>The need to know if Spotify is actively playing is as a result of there only being a play/pause toggle activated by spacebar. Without testing this locking the screen with Spotify already paused and open would result in it starting when you lock the screen.</p>
<p>You&#8217;ll need the following packages installed to get it to work:</p>
<pre><code>sudo apt-get install wmctrl xvkbd</code></pre>
<p>wmctrl is a window manager CLI tool and xvkbd is a vitual keyboard that also has a CLI interface to send keystrokes.</p>
<p>Here&#8217;s the script:</p>
<pre><code>#!/usr/bin/env bash # By Stuart Colville
# http://muffinresearch.co.uk/archives/2009/10/22/ubuntu-lock-screen-and-pause-spotify/
# sudo apt-get install wmctrl xvkbd # Check the title in the window list to work out if it's playing
TITLE=$(wmctrl -l | grep -o -e "Spotify.*$") # If it's playing pause it
if [[ "$TITLE" != Spotify ]]; then wmctrl -a "Spotify" &#038;&#038; xvkbd -q -delay 100 -text '&#92; '
fi # Lock the screen
gnome-screensaver-command --lock exit 0
</code></pre>
<p>Save it somewhere and make it executable e.g. <code>chmod +x ~/bin/lock_screen.sh</code>.</p>
<p>If you want it to work on a keycombo then just add an item to System -&gt; Preference -&gt; Keyboard Shortcuts</p>
<p><del datetime="2009-10-23T08:51:25+00:00">Known Issue: A problem I&#8217;ve spotted is that locking the screen causes Spotify to start playing if it&#8217;s open and paused. So I need to add a way to detect if Spotify is currently playing without which this script is pretty much useless.</del> <del datetime="2009-10-23T11:28:04+00:00">Fixed with libinotify-tools</del></p> 
<p><del datetime="2009-10-23T11:22:27+00:00">The <strong>EPIC Hack</strong> here is using libinotify to detect if Spotify is playing by watching file accesses to the Storage directory. Can&#8217;t help but feeling there&#8217;s got to be a better way. It also means that a delay of 5 secs is needed to wait for an event.</del> &#8211; <em>There was a better way!</em> This is now done by interogating the window list via wmctrl</p> 
<p>Updates and suggestions are welcomed.</p>
<div class="feedflare">
<a rel="nofollow" target="_blank" href="http://feeds.feedburner.com/~ff/muffinres/skimmed?a=xIxbLC9Tnr0:w2RFrJPJPe8:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/muffinres/skimmed?d=yIl2AUoC8zA" border="0"></a> <a rel="nofollow" target="_blank" href="http://feeds.feedburner.com/~ff/muffinres/skimmed?a=xIxbLC9Tnr0:w2RFrJPJPe8:2nqncYFp4_M"><img src="http://feeds.feedburner.com/~ff/muffinres/skimmed?d=2nqncYFp4_M" border="0"></a> <a rel="nofollow" target="_blank" href="http://feeds.feedburner.com/~ff/muffinres/skimmed?a=xIxbLC9Tnr0:w2RFrJPJPe8:7Q72WNTAKBA"><img src="http://feeds.feedburner.com/~ff/muffinres/skimmed?d=7Q72WNTAKBA" border="0"></a> <a rel="nofollow" target="_blank" href="http://feeds.feedburner.com/~ff/muffinres/skimmed?a=xIxbLC9Tnr0:w2RFrJPJPe8:2mJPEYqXBVI"><img src="http://feeds.feedburner.com/~ff/muffinres/skimmed?d=2mJPEYqXBVI" border="0"></a>
</div>]]></content:encoded>
      </item>
      <item>
         <title>Open Redirects and Phishing Vectors</title>
         <link>http://muffinresearch.co.uk/archives/2009/09/30/open-redirects-and-phishing-vectors/</link>
         <description>There was an interesting article on the Google Webmaster Central blog back in Jan talking about open redirects being abused by spammers.
One point they didn&amp;#8217;t go into too much detail on is that of phishing vectors. If you&amp;#8217;re running a site with any kind of user registration and you have a redirect script that allows [...]</description>
         <guid isPermaLink="false">http://muffinresearch.co.uk/?p=471</guid>
         <pubDate>Wed, 30 Sep 2009 15:43:52 -0700</pubDate>
         <content:encoded><![CDATA[<p><a rel="nofollow" target="_blank" href="http://muffinresearch.co.uk/i/redirect-attack2.png"><img class="bord" src="http://muffinresearch.co.uk/i/open-redirect.jpg" alt="Open Redirect Phishing Vector Diagram" height="291" width="540"/></a></p>
<p>There was an interesting article on the <a rel="nofollow" target="_blank" href="http://googlewebmastercentral.blogspot.com/2009/01/open-redirect-urls-is-your-site-being.html">Google Webmaster Central blog</a> back in Jan talking about open redirects being abused by spammers.</p>
<p>One point they didn&#8217;t go into too much detail on is that of phishing vectors. If you&#8217;re running a site with any kind of user registration and you have a redirect script that allows redirects to any arbitrary urls. Then it&#8217;s fairly likely that you&#8217;ve straight away made it possible for a 3rd party to phish your registration form.</p>
<p>Let&#8217;s see an example of how something like this would work, first a standard redirection script:</p>
<dl class='tb'>
<dt>Target Site</dt>
<dd>buyeverythingawesome.com</dd>
<dt>Attack URL</dt>
<dd>http://buyeverythingawesome.com/redirect?url=http://buyeverythingawesome<strong>e</strong>.com/login/</dd>
<dt>Attacker&#8217;s Bogus Domain</dt>
<dd>buyeverythingawesome<strong>e</strong>.com</dd>
</dl>
<p>The target site has a script which blindly redirects to anything passed to it.</p>
<p>All the attacker has to do is send a victim an email telling them to login to their account to view the latest offers. The link they send is <code>http://buyeverythingawesome.com/redirect?url=http://buyeverythingawesomee.com/login/</code></p>
<p>On the bogus domain the attacker will have prepared a copy of the site&#8217;s login screen. All they need to do is get the user to login and then redirect the user back to the original site and if possible directly to the failed login page of the original site.</p>
<p>The way to mitigate this is to only allow redirects to your internal site or provide a whitelist of external urls that are allowed to be redirected to. </p>
<h3>Open Redirect Login Script</h3>
<p>Open Redirects in a login script are even worse in a way as the attacker will send the user to the real site&#8217;s login script.</p>
<p>The symptoms of this kind of problem are visible with a setup like so:</p>
<dl class="tb">
<dt>Target Site</dt>
<dd>buyeverythingawesome.com</dd>
<dt>Attack URL</dt>
<dd>http://someawesomsite.com/login?after=http//:some<strong>w</strong>awesomsite.com/loginfailed/</dd>
<dt>Attacker&#8217;s Bogus Domain</dt>
<dd>some<strong>w</strong>awesomsite.com</dd>
</dl>
<p>All the attacker needs to do is to get the unwitting victim to visit <code>http://someawesomsite.com/login?after=http://some<strong>w</strong>awesomsite.com/loginfailed/</code></p>
<p>The user will be presented with the login screen for the genuine site. Once they login they are redirected to a bogus site with a &#8220;Your login has failed message &#8211; please try again&#8221; simply copied from the real site. The second time the user logs in they are logging-in to a bogus copy of the real site. Once the credentials are stolen the user can be redirected back to the real site where they are successfully logged in (This is because they aren&#8217;t redirected until they sucessfully login).</p>
<p>This is particularly nasty because the start and end points of this hack <em>are</em> the genuine site and as a result this kind of attack is much more likely to slip by unnoticed.</p>
<p>As a picture speaks a thousand words see this diagram of the flow: <a rel="nofollow" target="_blank" href="http://muffinresearch.co.uk/i/redirect-attack2.png">Open Redirect Phishing Vector (.png)</a></p>
<h3>Preventing these kind of attacks</h3>
<p>Firstly make absolutely sure you only allow redirects to internal links or whitelisted sites. If you need to redirect to arbitrary sites an interstitial page might be necessary to make it absolutely clear that the user is being redirected to a third party.</p>
<p>You might think that your site is already checking that links redirected are only internal ones. However it&#8217;s crucial that you take care to check more than just validating that the url starts with a slash.</p>
<h4>Check you&#8217;ve covered all eventualities</h4>
<p>It&#8217;s possible to write a link as <code>//foo.com</code> and the scheme (http/https etc) will be inherited from the base URI . So if you&#8217;re on <code>http://baz.com</code> and there&#8217;s a link with an href attribute of <code>//google.com</code> this will resolve to <code>http://google.com</code>. It&#8217;s therefore important that any validation of redirect URLs covers this case or you could be caught out. </p>
<p>Note: If you&#8217;re interested this aspect of how URIs work is covered by <a rel="nofollow" target="_blank" href="http://labs.apache.org/webarch/uri/rfc/rfc3986.html#reference-examples">examples given in rfc 3986</a></p>
<p>As an example<code> http://has-open-redirect.com/login/?done=//google.com</code> would redirect to <code>http://google.com</code> after login if vulnerable.</p>
<h3>Why is any of this important?</h3>
<p>Right now you&#8217;re probably thinking that there&#8217;s nothing behind the login to your site that a hacker would want.</p>
<p>However, have you stopped to consider that your users might also use the same username and password to login to their amazon account for example?</p>
<p>Lot&#8217;s of people will only have one username and password for every site they use (<a rel="nofollow" target="_blank" href="http://www.infosecurity-magazine.com/view/3779/many-people-use-same-password-on-all-websites-says-cpp/">this infosecurity magazine article claims 46% of all UK adults us the same password</a>). If it&#8217;s possible to phish accounts on a low profile site &#8211; the chances are there will come a point when the attacker will hit the jackpot and get access to every site that user frequents with same username and password. </p>
<p class="update">Update: The GMail team has a nice post detailing some good <a rel="nofollow" target="_blank" href="http://gmailblog.blogspot.com/2009/10/choosing-smart-password.html">tips for choosing a good password</a>. Tip number one is don&#8217;t use the same password for all sites</p>
<div class="feedflare">
<a rel="nofollow" target="_blank" href="http://feeds.feedburner.com/~ff/muffinres/skimmed?a=zH2S9iuIkDQ:vGZill7Lu2o:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/muffinres/skimmed?d=yIl2AUoC8zA" border="0"></a> <a rel="nofollow" target="_blank" href="http://feeds.feedburner.com/~ff/muffinres/skimmed?a=zH2S9iuIkDQ:vGZill7Lu2o:2nqncYFp4_M"><img src="http://feeds.feedburner.com/~ff/muffinres/skimmed?d=2nqncYFp4_M" border="0"></a> <a rel="nofollow" target="_blank" href="http://feeds.feedburner.com/~ff/muffinres/skimmed?a=zH2S9iuIkDQ:vGZill7Lu2o:7Q72WNTAKBA"><img src="http://feeds.feedburner.com/~ff/muffinres/skimmed?d=7Q72WNTAKBA" border="0"></a> <a rel="nofollow" target="_blank" href="http://feeds.feedburner.com/~ff/muffinres/skimmed?a=zH2S9iuIkDQ:vGZill7Lu2o:2mJPEYqXBVI"><img src="http://feeds.feedburner.com/~ff/muffinres/skimmed?d=2mJPEYqXBVI" border="0"></a>
</div>]]></content:encoded>
      </item>
      <item>
         <title>Distraxion</title>
         <link>http://muffinresearch.co.uk/archives/2009/09/16/distraxion/</link>
         <description>Brilliant animation &amp;#8211; and nails exactly how I feel about Smooth Jazz. via BoingBoing</description>
         <guid isPermaLink="false">http://muffinresearch.co.uk/?p=686</guid>
         <pubDate>Wed, 16 Sep 2009 05:01:28 -0700</pubDate>
         <content:encoded><![CDATA[<p><iframe class="embeddedvideo" src="http://www.youtube.com/v/uxezt4Ks5XA&#038;hl=en&#038;fs=1&#038;rel=0" type="application/x-shockwave-flash" width="425" height="344"></iframe></p>
<p>Brilliant animation &#8211; and nails exactly how I feel about Smooth Jazz. via <a rel="nofollow" target="_blank" href="http://www.boingboing.net/2009/09/15/animated-short-about.html">BoingBoing</a></p>
<div class="feedflare">
<a rel="nofollow" target="_blank" href="http://feeds.feedburner.com/~ff/muffinres/skimmed?a=Wio8SwQW-Tc:ZO5f_Jlw7Nc:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/muffinres/skimmed?d=yIl2AUoC8zA" border="0"></a> <a rel="nofollow" target="_blank" href="http://feeds.feedburner.com/~ff/muffinres/skimmed?a=Wio8SwQW-Tc:ZO5f_Jlw7Nc:2nqncYFp4_M"><img src="http://feeds.feedburner.com/~ff/muffinres/skimmed?d=2nqncYFp4_M" border="0"></a> <a rel="nofollow" target="_blank" href="http://feeds.feedburner.com/~ff/muffinres/skimmed?a=Wio8SwQW-Tc:ZO5f_Jlw7Nc:7Q72WNTAKBA"><img src="http://feeds.feedburner.com/~ff/muffinres/skimmed?d=7Q72WNTAKBA" border="0"></a> <a rel="nofollow" target="_blank" href="http://feeds.feedburner.com/~ff/muffinres/skimmed?a=Wio8SwQW-Tc:ZO5f_Jlw7Nc:2mJPEYqXBVI"><img src="http://feeds.feedburner.com/~ff/muffinres/skimmed?d=2mJPEYqXBVI" border="0"></a>
</div>]]></content:encoded>
         <category>humour</category>
      </item>
      <item>
         <title>Cross Platform Keyring Library for Python</title>
         <link>http://muffinresearch.co.uk/archives/2009/08/26/cross-platform-keyring-library-for-python/</link>
         <description>Kang Zhang has been busy on a Google Summer of Code project to create a cross platform keychain library for Python.
The Python keyring lib provides a easy way to access the system keyring service from python. It can be used in any application that needs safe password storage. It supports OSX, KDE, Gnome and Windows&amp;#8217;s [...]</description>
         <guid isPermaLink="false">http://muffinresearch.co.uk/?p=673</guid>
         <pubDate>Wed, 26 Aug 2009 03:18:46 -0700</pubDate>
         <content:encoded><![CDATA[<p><a rel="nofollow" target="_blank" href="http://kangzhang.org/">Kang Zhang</a> has been busy on a Google Summer of Code project to create a cross platform keychain library for Python.</p>
<blockquote><p>The Python keyring lib provides a easy way to access the system keyring service from python. It can be used in any application that needs safe password storage. It supports OSX, KDE, Gnome and Windows&#8217;s native password storing services. Besides this, it is shipped with kinds of Python implemented keyring for the left environments.</p>
</blockquote>
<p>It&#8217;s also been written in a way that makes it possible to create your own Keyring backend if you want to. </p>
<p>As this provides a native Python interface to the OSX keychain I&#8217;d certainly recommend looking at this over and above my own noddy OSX keychain wrapper. </p>
<p>Good stuff!</p>
<p>See the site for more info: <a rel="nofollow" target="_blank" href="http://home.python-keyring.org">http://home.python-keyring.org</a></p>
<div class="feedflare">
<a rel="nofollow" target="_blank" href="http://feeds.feedburner.com/~ff/muffinres/skimmed?a=vhsGqexvI1g:aohU_D0NgUc:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/muffinres/skimmed?d=yIl2AUoC8zA" border="0"></a> <a rel="nofollow" target="_blank" href="http://feeds.feedburner.com/~ff/muffinres/skimmed?a=vhsGqexvI1g:aohU_D0NgUc:2nqncYFp4_M"><img src="http://feeds.feedburner.com/~ff/muffinres/skimmed?d=2nqncYFp4_M" border="0"></a> <a rel="nofollow" target="_blank" href="http://feeds.feedburner.com/~ff/muffinres/skimmed?a=vhsGqexvI1g:aohU_D0NgUc:7Q72WNTAKBA"><img src="http://feeds.feedburner.com/~ff/muffinres/skimmed?d=7Q72WNTAKBA" border="0"></a> <a rel="nofollow" target="_blank" href="http://feeds.feedburner.com/~ff/muffinres/skimmed?a=vhsGqexvI1g:aohU_D0NgUc:2mJPEYqXBVI"><img src="http://feeds.feedburner.com/~ff/muffinres/skimmed?d=2mJPEYqXBVI" border="0"></a>
</div>]]></content:encoded>
         <category>Code</category>
      </item>
      <item>
         <title>PHP: Multiple DNS Queries Using fopen</title>
         <link>http://muffinresearch.co.uk/archives/2009/08/12/php-multiple-dns-queries-using-fopen/</link>
         <description>Whilst working on some inherited PHP code that used fopen I noticed an interesting comment in the PHP manual which pointed out that fopen always makes a DNS lookup for every request. Taking the following code as an example:
&amp;#60;?php
$handle = fopen(&quot;http://muffinresearch.co.uk/robots.txt&quot;, &quot;r&quot;);
$contents = stream_get_contents($handle); // PHP5+ ONLY
echo $contents;
?&amp;#62;
Using wireshark for capturing and calling that script [...]</description>
         <guid isPermaLink="false">http://muffinresearch.co.uk/?p=660</guid>
         <pubDate>Wed, 12 Aug 2009 11:03:16 -0700</pubDate>
         <content:encoded><![CDATA[<p>Whilst working on some inherited PHP code that used <code>fopen</code> I noticed an interesting <a rel="nofollow" target="_blank" href="http://uk3.php.net/manual/en/function.fopen.php#73132">comment</a> in the PHP manual which pointed out that fopen always makes a DNS lookup for every request. Taking the following code as an example:</p>
<pre><code>&lt;?php
$handle = fopen("http://muffinresearch.co.uk/robots.txt", "r");
$contents = stream_get_contents($handle); // PHP5+ ONLY
echo $contents;
?&gt;</code></pre>
<p>Using <a rel="nofollow" target="_blank" href="http://www.wireshark.org/">wireshark</a> for capturing and calling that script 3 times I got 3 DNS lookups because fopen doesn&#8217;t make use of any DNS lookup caches:</p>
<p><img src="http://muffinresearch.co.uk/i/fopen-wireshark.png" alt="Wireshark dialogue showing 3 DNS queries for muffinresearch.co.uk"/></p>
<p>Not only is this a problem for fopen but I also found the same problem with file_get_contents too.</p>
<p>The comment in the manual suggests using <code>gethostbyname</code> which uses the DNS cache. You can then use this to provide the ip address in the arguments to fopen. However as soon as you&#8217;re trying to fetch something which uses name-based virtual hosts this approach will fail. This is due to there being several sites on the same server all being served on the same ip address; if you contact the server by ip address it will simply serve you content from the default virtual host which is the conf which happens to be first alphabetically.</p>
<h3>A Solution</h3>
<p>The cURL library (php5-curl is the package you&#8217;ll need on Ubuntu) <em>is</em> the preferred way of fetching content with PHP, mainly because it gives you far greater control over requests.</p>
<p>The other big benefit of using cURL is that it makes use of the DNS cache so we can save a DNS lookup for repetitive calls to the same hostname:</p>
<pre><code>&lt;?php $ch = curl_init(); curl_setopt($ch, CURLOPT_URL, "http://muffinresearch.co.uk/robots.txt"); curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); $output = curl_exec($ch); echo $output; curl_close($ch);
?&gt;</code></pre>
<p>Running that script three times now results in only one DNS request (I manually cleared the DNS cache with <code>sudo /etc/init.d/networking restart</code> first)</p>
<p><img class="bord" src="http://muffinresearch.co.uk/i/wireshark-curl.png" alt="Wireshark dialogue showing 1 DNS query for muffinresearch.co.uk"/></p>
<h3>Conclusion</h3>
<p>If you&#8217;re using php to fetch data from the web cURL is a much more powerful solution than relying on <code>fopen</code> or <code>file_get_contents</code>. Not only that if you&#8217;re fetching a lot of data from the same hosts frequently your scripts will run faster as a result of only making the minimum DNS requests.</p>
<div class="feedflare">
<a rel="nofollow" target="_blank" href="http://feeds.feedburner.com/~ff/muffinres/skimmed?a=G_smyk6yj60:ImROEmx8o-4:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/muffinres/skimmed?d=yIl2AUoC8zA" border="0"></a> <a rel="nofollow" target="_blank" href="http://feeds.feedburner.com/~ff/muffinres/skimmed?a=G_smyk6yj60:ImROEmx8o-4:2nqncYFp4_M"><img src="http://feeds.feedburner.com/~ff/muffinres/skimmed?d=2nqncYFp4_M" border="0"></a> <a rel="nofollow" target="_blank" href="http://feeds.feedburner.com/~ff/muffinres/skimmed?a=G_smyk6yj60:ImROEmx8o-4:7Q72WNTAKBA"><img src="http://feeds.feedburner.com/~ff/muffinres/skimmed?d=7Q72WNTAKBA" border="0"></a> <a rel="nofollow" target="_blank" href="http://feeds.feedburner.com/~ff/muffinres/skimmed?a=G_smyk6yj60:ImROEmx8o-4:2mJPEYqXBVI"><img src="http://feeds.feedburner.com/~ff/muffinres/skimmed?d=2mJPEYqXBVI" border="0"></a>
</div>]]></content:encoded>
         <category>Code</category>
      </item>
      <item>
         <title>VirtualBox: Error: Cannot register the hard disk</title>
         <link>http://muffinresearch.co.uk/archives/2009/07/23/virtualbox-error-cannot-register-the-hard-disk/</link>
         <description>If when cloning VirtualBox VMs you get an error like this:
$ VBoxManage clonehd WinXP-IE7.vdi WinXP-IE8.vdi
VirtualBox Command Line Management Interface Version 2.2.4
(C) 2005-2009 Sun Microsystems, Inc.
All rights reserved. ERROR: Cannot register the hard disk '/home/scol/.VirtualBox/VDI/WinXP-IE7.vdi' with UUID {3858b1b1-c306-4505-8264-235af812f337} because a hard disk '/home/scol/.VirtualBox/VDI/WinXP-IE7.vdi' with UUID {3858b1b1-c306-4505-8264-235af812f337} already exists in the media registry ('/home/scol/.VirtualBox/VirtualBox.xml')
Details: code NS_ERROR_INVALID_ARG (0x80070057), component [...]</description>
         <guid isPermaLink="false">http://muffinresearch.co.uk/?p=653</guid>
         <pubDate>Thu, 23 Jul 2009 03:27:08 -0700</pubDate>
         <content:encoded><![CDATA[<p>If when cloning VirtualBox VMs you get an error like this:</p>
<pre><code>$ VBoxManage clonehd WinXP-IE7.vdi WinXP-IE8.vdi
VirtualBox Command Line Management Interface Version 2.2.4
(C) 2005-2009 Sun Microsystems, Inc.
All rights reserved. ERROR: Cannot register the hard disk '/home/scol/.VirtualBox/VDI/WinXP-IE7.vdi' with UUID {3858b1b1-c306-4505-8264-235af812f337} because a hard disk '/home/scol/.VirtualBox/VDI/WinXP-IE7.vdi' with UUID {3858b1b1-c306-4505-8264-235af812f337} already exists in the media registry ('/home/scol/.VirtualBox/VirtualBox.xml')
Details: code NS_ERROR_INVALID_ARG (0x80070057), component VirtualBox, interface IVirtualBox, callee nsISupports
Context: "OpenHardDisk(Bstr(szFilenameAbs), AccessMode_ReadWrite, srcDisk.asOutParam())" at line 603 of file VBoxManageDisk.cpp</code></pre>
<p>Talk about a completely ambiguous error message! The solution is to provide an absolute path to the source VDI and target VDIs (leaving the path off the target will put the image in ~/.VirtualBox/HardDisks by default):</p>
<pre><code>$ VBoxManage clonehd $(pwd)/WinXP-IE7.vdi $(pwd)/WinXP-IE8.vdi
VirtualBox Command Line Management Interface Version 2.2.4
(C) 2005-2009 Sun Microsystems, Inc.
All rights reserved. 0%...10%...20%...30%...40%...50%...60%...70%...80%...90%...100%
Clone hard disk created in format 'VDI'. UUID: b7166421-9743-4808-aedf-3c90aeb7c902</code></pre>
<div class="feedflare">
<a rel="nofollow" target="_blank" href="http://feeds.feedburner.com/~ff/muffinres/skimmed?a=eyFhEcuYRyY:u4EU2NlXX3A:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/muffinres/skimmed?d=yIl2AUoC8zA" border="0"></a> <a rel="nofollow" target="_blank" href="http://feeds.feedburner.com/~ff/muffinres/skimmed?a=eyFhEcuYRyY:u4EU2NlXX3A:2nqncYFp4_M"><img src="http://feeds.feedburner.com/~ff/muffinres/skimmed?d=2nqncYFp4_M" border="0"></a> <a rel="nofollow" target="_blank" href="http://feeds.feedburner.com/~ff/muffinres/skimmed?a=eyFhEcuYRyY:u4EU2NlXX3A:7Q72WNTAKBA"><img src="http://feeds.feedburner.com/~ff/muffinres/skimmed?d=7Q72WNTAKBA" border="0"></a> <a rel="nofollow" target="_blank" href="http://feeds.feedburner.com/~ff/muffinres/skimmed?a=eyFhEcuYRyY:u4EU2NlXX3A:2mJPEYqXBVI"><img src="http://feeds.feedburner.com/~ff/muffinres/skimmed?d=2mJPEYqXBVI" border="0"></a>
</div>]]></content:encoded>
      </item>
      <item>
         <title>Project Fondue Blog</title>
         <link>http://muffinresearch.co.uk/archives/2009/07/14/project-fondue-blog/</link>
         <description>Last weekend I was in Paris with Cyril and Ed spending some time on Project Fondue Projects. One of the things we got done was putting out the initial iteration of the Project Fondue Blog. This is based on Pocoo&amp;#8217;s Zine which we&amp;#8217;ve really enjoyed using. The only downside so far is that it&amp;#8217;s dependencies [...]</description>
         <guid isPermaLink="false">http://muffinresearch.co.uk/?p=650</guid>
         <pubDate>Tue, 14 Jul 2009 04:16:16 -0700</pubDate>
         <content:encoded><![CDATA[<p>Last weekend I was in Paris with Cyril and Ed spending some time on Project Fondue Projects. One of the things we got done was putting out the initial iteration of the <a rel="nofollow" target="_blank" href="http://blog.projectfondue.com/">Project Fondue Blog</a>. This is based on <a rel="nofollow" target="_blank" href="http://zine.pocoo.org/">Pocoo&#8217;s Zine</a> which we&#8217;ve really enjoyed using. The <em>only</em> downside so far is that it&#8217;s dependencies are quite cutting edge so if you are sticking to older Debian based distros (in our case Hardy LTS) it&#8217;s a case of pulling together the necessary packages from Debian Repos.</p>
<p>I&#8217;d certainly recommend subscribing to the <a rel="nofollow" target="_blank" href="http://blog.projectfondue.com/feed.atom">rss feed</a> &#8211; as there will be some interesting posts coming up. </p>
<div class="feedflare">
<a rel="nofollow" target="_blank" href="http://feeds.feedburner.com/~ff/muffinres/skimmed?a=Nj5l5R4-gNU:QEHmdVJ3YHM:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/muffinres/skimmed?d=yIl2AUoC8zA" border="0"></a> <a rel="nofollow" target="_blank" href="http://feeds.feedburner.com/~ff/muffinres/skimmed?a=Nj5l5R4-gNU:QEHmdVJ3YHM:2nqncYFp4_M"><img src="http://feeds.feedburner.com/~ff/muffinres/skimmed?d=2nqncYFp4_M" border="0"></a> <a rel="nofollow" target="_blank" href="http://feeds.feedburner.com/~ff/muffinres/skimmed?a=Nj5l5R4-gNU:QEHmdVJ3YHM:7Q72WNTAKBA"><img src="http://feeds.feedburner.com/~ff/muffinres/skimmed?d=7Q72WNTAKBA" border="0"></a> <a rel="nofollow" target="_blank" href="http://feeds.feedburner.com/~ff/muffinres/skimmed?a=Nj5l5R4-gNU:QEHmdVJ3YHM:2mJPEYqXBVI"><img src="http://feeds.feedburner.com/~ff/muffinres/skimmed?d=2mJPEYqXBVI" border="0"></a>
</div>]]></content:encoded>
         <category>Project Fondue</category>
      </item>
      <item>
         <title>The difference between a web developer and an engineer</title>
         <link>http://www.isolani.co.uk/blog/web/DifferenceBetweenAWebDeveloperAndEngineer</link>
         <guid isPermaLink="false">gg6L8PuW3BGXJwFvjtzu1g_74ed50cbedae2b1714dd009b33744751</guid>
         <pubDate>Sun, 29 Nov 2009 20:09:10 -0800</pubDate>
         <content:encoded><![CDATA[<p>An engineer builds platforms. A web developer creates websites using those platforms.</p>]]></content:encoded>
      </item>
      <item>
         <title>Symfony 1.3 Web Application Development</title>
         <link>http://www.isolani.co.uk/blog/reviews/Symfony13WebApplicationDevelopment</link>
         <guid isPermaLink="false">gg6L8PuW3BGXJwFvjtzu1g_c477eac6334d4a1808a78016ba03a341</guid>
         <pubDate>Sun, 29 Nov 2009 20:09:10 -0800</pubDate>
         <content:encoded><![CDATA[<p>Title: <a rel="nofollow" target="_blank" href="http://www.packtpub.com/symfony-1-3-web-application-development/book">Symfony 1.3 Web Application Development</a> (on <a rel="nofollow" target="_blank" href="http://www.amazon.co.uk/gp/product/1847194567?ie=UTF8&amp;tag=getsmalea-21&amp;linkCode=as2&amp;camp=1634&amp;creative=19450&amp;creativeASIN=1847194567">Amazon.co.uk</a>)<br />
Authors: Tim Bowler, Wojciech Bancer<br />
Publisher: Packt Press<br />
Publish Date: September 2009</p> <p>Disclaimer: I received a review copy of this book from Packt Publishing in September 2009.</p> <p><img class="bookPic" width="240" height="240" alt="" src="http://ecx.images-amazon.com/images/I/41mRjITuWbL._SL500_AA240_.jpg"/>
Symfony is a PHP5 framework for rapidly building dynamic web applications. This book is targeted at Symfony 1.3 when it hits production-ready status. At the time of writing the 1.3 version is still in alpha. Unfortunately this book suffers from the uncertainly as final decisions haven't been made. The major one is whether the default ORM will be Propel or Doctrine. The book flip-flops on which one is the default ORM. On the whole the book feels like a rushed job, trying to get to market before Symfony 1.3 hits production ready.</p> <p>The <a rel="nofollow" target="_blank" href="http://www.symfony-project.org/">Symfony project</a> themselves have useful introductions to using Symfony, most particularly their <a rel="nofollow" target="_blank" href="http://www.symfony-project.org/jobeet/1_2/Doctrine/en/">Jobeet tutorial</a> which covers Symfony through the practical development of a Job listing site. This new book by Packt attempts the same approach, building a website for a chain of milkshake restaurants. It is a decent example that covers many of the features of Symfony, and so comparing it to the Jobeet tutorial is a useful exercise.</p> <p>The intended audience for this book are developers using older versions of Symfony as well as developers new to Symfony. I'm fairly new to Symfony and I've been developing with it for almost a year now.</p> <h3>Overview of the book</h3> <p>The first chapter of Symfony 1.3 Web Application Development covers getting and setting up Symfony. The next chapter sets out the skeleton of our application by defining the database schema, routing, actions and templates. This is followed by a chapter on adding business logic to to model and adding navigation. A chapter on building a simple form to email module takes us through Symfony Forms, and then takes us through converting it into a reusable plugin.</p> <p>Then we create the administration interface through chapter 5, customising the admin screens as well as locking parts down through authentication. Chapter 6 covers adding Javascript to the admin interface by adding an image uploading widget, a date picker and rich text editing.</p> <p>Chapter 7 shows off some of Symfony's internationalisation and localisation features. There follows a chapter on adding 3rd party libraries to symfony, and a useful chapter on various caching layers in Symfony. The final chapter talks about deploying your application to a production environment.</p> <h3>Building the skeleton of the application</h3> <p>The chapter on setting up Symfony and creating the skeleton of the application competes directly with the Jobeet tutorial, and unfortunately comes off second best. The approach the book takes to installing Symfony is to grab the current version from the Symfony SVN repository and then create a sandbox using that code. This is different to the preferred Symfony 1.2 method of doing an SVN checkout to the <code>lib/vendor</code> directory of each project.</p> <p>What I found bizarre was the authors' preference for using the Propel XML schema format for defining the database instead of Symfony's consistent YAML methods. The authors state that they find YAML more difficult to read and with spaces instead of tabs this causes problems with large YAML files such as a database schema. I find this puzzling since all of Symfony's configuration is done with YAML, so it's impossible to avoid - the authors later have to teach the reader how to do YAML anyway, so introducing the XML way is just not efficient.</p> <p>And introducing the XML vocabulary they don't. There's two pages of database schema in XML format, and they explain just 4 attributes of the entire document. No mention is made of the structure, or the purpose of the elements, let alone the various field types that are allowed. The whole XML way of defining a database schema looks left as an exercise for the reader.</p> <p>The HTML in the code examples left me horrified. Essentially the page layout template is a set of <code>div</code>s with inline style attributes. Including the 5 item navigation list, each <code>li</code> having the same three lines of inline style properties. I'm astonished that in the 21st century we have such a poor understanding of CSS from people teaching development on the Web. Jobeet beats the pants off this section of the book by embracing the customisability and flexibility of CSS by creating a competition for skinning their application - that's perfect web standards evangelism. This Packt Press book however, shows a lack of modern web development techniques that have been prevalent over at least the last four years.</p> <p>The attention to detail is lacking. There's no mention of how to configure the web server to serve content from the web directory. Considering that the book heavily uses the custom domain <samp>milkshake</samp>, leaving out the web server configuration is a disservice to the reader, since they can't really follow along with the book. Again, this seems to be another exercise for the reader with no clear guidance given of what needs doing. A passing mention of aliasing the Symfony assets directory is the closest the book comes to the web server configuration. Jobeet covers this particularly well in day one of their tutorial.</p> <h3>Dealing with business logic</h3> <p>The chapters covering adding in more complicated business logic are better, they feel that they hold together better than the previous chapters. It takes the reader through creating new modules and adding in custom logic, as well as getting hold of request-related information. The routing sections are decently explained. Particularly the explanation of pagination and partials were well written.</p> <p>The next chapter on creating a newsletter signup script, so taking a form, adding the received data to a database and firing off an email is a good chapter, the plugin section being extremely useful. It introduces the Symfony Forms feature as we build the module from a database schema and generate the form classes before customising them in both the structure of the form and how it is rendered on screen.</p> <p>As an accessibility practitioner, I'm noticing that there's no mention of explicit HTML <code>label</code>s and grouping by <code>fieldset</code>s, and the error handling on form validation leaves little to be desired. Still, it sounds like that these renderers can be rewritten to produce accessible markup.</p> <p>Security is covered by the vaguest wave to a CSRF token (Cross Site Request Forgery), and that this hidden input field code snippet helps prevent this. Honestly, that is the coverage of security in its entirety. I understand that this book isn't about teaching security to web developers. The Jobeet tutorial is <a rel="nofollow" target="_blank" href="http://www.symfony-project.org/jobeet/1_2/Propel/en/11#chapter_11_sub_xss_and_csrf_protection">slightly better in this regard</a>, but not by much.</p> <p>There's no detail on where or how to use third party libraries involved in email delivery. The code example assumes that the library is already installed at the correct location and ready to be used.</p> <p>The section of creating a plugin is perhaps the most useful section, taking the reader through the steps of creating a reusable plugin for modules. Perfect for isolating bits of code to use in other projects. The higher level process is easy to understand, but the actual implementation is under a cloud because of the setup concerns of the first chapter. I hope the actual step-by-step process is correct, and that really means this book needs to be properly tech-edited and proof-read by a hands on developer.</p> <h3>Configuring the Administration area</h3> <p>I struggled getting the admin area working through the Jobeet tutorial, so I'm happy to say that the process of customising the administration configuration makes a lot more sense after reading this chapter. Particularly, I found the Jobeet process of locking down access to the adminstration side of the application made even the login page requiring authentication before being accessed (possibly I needed to clear the cache?). This book makes a more determined effort to explain how the authentication system works and how it is configured, so that fills me with more confidence.</p> <p>The chapter on enhancing forms with Ajax came as a surprise as they added the functionality to the adminstration area instead of a simple form outside. That shows the confidence of the author to pull this off. I hope it works.</p> <h3>Internationalisation</h3> <p>It's another useful chapter, this time on internationalising the application. The chapter takes the reader through extending the database schema to handle translations of each piece of content, and the changes needed to address the model to reflect the selected locale (the authors use the term 'culture' for locale).</p> <p>For localising the templates and interface text the book steps through using XLIFF (XML Localisation Interchange File Format) which takes a text string as a key and returns a translation that's stores in the XML translation files. There are automated tools to extract existing text from templates to populate the initial files. And then filtering all static text through a special filter function produces the correct translations.</p> <p>However, after being through an internationalisation hell for the latter half of 2008, I realise the book isn't anywhere near complete in it's internationalisation coverage. There's no mention of handling static text that contains request-variable information, like <q>This is page 6 of 12</q>, nor any mention of Symfony's ordinal and plural grouping of numbers which impressed me in its ability to handle Polish. Nor was there any mention of currency, number or date formatting.</p> <p>Granted that translating plain text is a major step forward for being able to localise sites, but it's one step in a series of steps. (This is despite the code examples containing mojibake, presumably because the printing process of the book is at fault here)</p> <h3>Extending Symfony, Performance and Deployment</h3> <p>This chapter covers using other PHP5 libraries inside of Symfony. The demonstration of using ez Component's Pie Chart component inside a Symfony application impressed me, and again demonstrates the confidence of the authors. Unfortunately the followup about integrating Zend framework components is two paragraphs and feels completely unfinished.</p> <p>The performance chapter covers the various cache levels of Symfony. Right from configuring gzip encoding within symfony, to template cache and data caches, and even when to avoid using the ORM when raw performance is necessary. The step by step guide is very useful, as we watch the load times of the page shrink drastically.</p> <p>The chapter on deployment covers how to disable a Symfony application, enable outage messages, and then recommends using rsync to migrate code from the development environment to production. It's a very quick overview of rsync.</p> <h3>Conclusion</h3> <p>There is a fair amount of useful information in this book. I will be using it's plugins and administration chapters again fairly soon. But this book suffers badly, it really needs a solid technical review and a very sharp editor review. It needs a proper developer test - take a developer who has no knowledge of Symfony and get them to follow along with the book.</p> <p>One serious issue was the <q>Finishing off the location page</q> section of Chapter 3 is supposed to cover adding in vacancies on the page, which is assumed to be there in Chapter 5's <q>Handling foreign keys using admin generator</q>.</p> <p>My gripe against the use of XML will be alleviated by either explaining the XML syntax of the database schema, or switch back to YAML. (But it would also help having a typesetting review of the book, the indenting of the code examples - including the YAML code snippets - aren't correct or consistent.)</p> <p>To be honest, I would wait for the second edition of this book; and only if it's strictly tech-edited, sternly proofread and typeset reviewed, after the first release of Symfony 1.3. It can be quite a good companion book to the Symfony framework, it's just not ready yet. When it is, it will be a useful guide to Symfony 1.3</p>]]></content:encoded>
      </item>
      <item>
         <title>The Bletchley Park experience</title>
         <link>http://www.isolani.co.uk/blog/misc/BletchleyParkExperience</link>
         <guid isPermaLink="false">gg6L8PuW3BGXJwFvjtzu1g_d973ce670838d86cb7458096ac672cff</guid>
         <pubDate>Sun, 29 Nov 2009 20:09:07 -0800</pubDate>
         <content:encoded><![CDATA[<p>On the 18th July 2009 a rag-tag army of geeks invaded Bletchley Park. Thanks to the genius of <a rel="nofollow" target="_blank" href="http://neilcrosby.com/">Neil Crosby</a>'s unorganising <a rel="nofollow" target="_blank" href="http://biggeekdayout.com/">Big Geek Day Out</a>. However, the geeks were spotted well in advance by the Bletchley Park organisation, and soundly routed and disarmed and subject to a wonderful show of hospitality and an abundant knowledge.</p> <h3>Britain's best-kept secret</h3> <p><a rel="nofollow" target="_blank" href="http://www.bletchleypark.org.uk/">Bletchley Park</a> is one of Britain's best-kept secrets of World War II, it was instrumental in shortening the duration of the War, being positively involved in every major conflict. It was a collection of talent and genius; staffed with mathematicians, engineers, linguists, chess players and demon crossword puzzle solvers. They quietly carried out their duty, careful never to break the seal of secrecy. And even twenty-five years after the end of World War II, the public still had no idea what happened at Bletchley Park. When the official secrecy expired and those records were made public for the first time in the mid 1970s we started to see the marvelous and ingenious work successfully executed by the collaboration of brains at Bletchley Park.</p> <p>I think Bletchley Park exemplifies the quiet British determination and grit, its quirky inventiveness and eccentricities even at the most desperate of times. It's also a fascinating story of modesty, and so many of the people of Bletchley Park never received the recognition they so richly deserved - even today.</p> <p>In war we glorify the conquerors - Eisenhower, Montgomery, Rommel, Doernitz - the people who made their names on the field of battle. We worship the political leaders Roosevelt and Churchill. Sometimes we remember the operatives working well behind enemy lines always in danger of being caught every moment of their lives. But for a few geeks sitting in wooden huts safely ensconced hours north of London, they are so easy to overlook, and yet their contribution to the defence of Europe is absolutely massive.</p> <p>Bletchley Park was the center of Britain's intelligence war against the Axis powers. It principally was devoted to cracking and translating messages between the enemy military units, but it also ran counter-intelligence and special operations.</p> <p>The main story of Bletchley Park is the story of Enigma and Bombe, and the codebreakers. Enigma, the machine that encrypted German military communications, and Bombe, the British machine that sought to break that encryption.</p> <h3>Cracking Enigma with Social Engineering</h3> <p>The breaking of Enigma wasn't all brute force. The codebreakers had a number of cribs - or techniques to reduce the possibilities - and many of them, as is thematic even in modern day codebreaking are down to social engineering. But in Bletchley Park's case it was reverse social engineering. Understanding habits of Enigma operators or message senders, and exploit it to reduce the possibilities.</p> <p>One particular brilliant piece of social engineering was finding duplicate messages. If you have the entire encrypted message and you can with reasonably certainty guess the start of the message then we immediately narrow the possibilities of setup because we know how the first few letters are translated. That crib is then handwired into Bombe, and it spouts out possible starting settings that result in the matched combinations of letters.</p> <p>There were a number of sources of these messages, the first was weather messages sent to U-Boats in the Atlantic, the German navy used standard weather reporting. So if the codebreakers could guess the weather pattern they could be reasonably certain of the decrypted message, so had a menu for the Bombe to process.</p> <p>Why crack a message you already know? Well, the German military made one gigantic mistake - mainly out of confidence that Enigma was unbreakable. The Enigma start settings were the same for everyone in the same branch of the military, so breaking that one known message meant that they had the Enigma settings for all messages sent by the same branch of the military of that day.</p> <p>The second piece of social engineering was a small German army unit in the middle of the North African desert. They sent virtually the identical message everyday reporting through their chain of command. Every day the message was "Nothing to report". That's enough of a menu for Bombe to brute force it's way to a solution. Now, what was utterly brilliant was Bletchley Park's request that the British Army in North Africa not send any of their units into the area this German unit was based. And so, the codebreakers virtually guaranteed that everyday they had the same message arriving ready for them to break the current day's settings.</p> <p>Another source of repetitive messages were commands issues from near the top of the military hierarchy. They often started with the formal "Special Orders/Instructions" (out of habit essentially). So frequently the codebreakers guessed certain messages would start with the German word "Besonder".</p> <p>I was amazed that social engineering was a critical part of breaking Enigma. Kevin Mitnick infamously demonstrated the power of social engineering in cracking computer systems, but the Bletchley Park codebreakers had already proved how effective it can be.</p> <h3>Chess and Bletchley Park</h3> <p>The 1939 Chess Olympiad in Buenos Aires was interrupted by the outbreak of World War 2. On the English team were <a rel="nofollow" target="_blank" href="http://en.wikipedia.org/wiki/Stuart_Milner-Barry">Stuart Milner-Barry</a> (later knighted), <a rel="nofollow" target="_blank" href="http://en.wikipedia.org/wiki/Conel_Hugh_O%27Donel_Alexander">Conel Hugh O'Donel Alexander</a> (or just Hugh Alexander) and <a rel="nofollow" target="_blank" href="http://en.wikipedia.org/wiki/Harry_Golombek">Harry Golombek</a>. All three left immediately and made their way back to Britain. Milner-Barry was the first to be recruited into Bletchley Park, and he in turn recruited both Alexander and Golombek.</p> <p>So three of the best chess players in England were part of the Bletchley Park intelligence war. Each contributed substantially in their own way.</p> <p>Milner-Barry headed up Hut 6 under Gordon Welchman, was later the person chosen to hand-deliver that petition to Winston Churchill begging for funding to keep the Bletchley Park operation going, which in turn Churchill became a staunch supporter of Bletchley Park's efforts. (Sir Stuart reprised that role by hand delivering a letter to John Major pleading for the preservation of Bletchley Park in 1992).</p> <p>Hugh Alexander became the head of Hut 8 (the Enigma code-breaking effort), taking over from <a rel="nofollow" target="_blank" href="http://en.wikipedia.org/wiki/Alan_Turing">Alan Turing</a>, becoming an instrumental part of the code breaking efforts. In Building B they recognise 4 individuals in particular for their efforts during the War. Turing was one of them, so was Gordon Welchman and Alexander was another.</p> <p>After the war Alexander was recruited into GCHQ, and that basically killed off his chess ambitions. In a radio-match he beat the Russian champion Mikhail Botvinnik (who was regarded as the strongest player in the post-war world, and two years later becoming World Chess Champion). Unfortunately Alexander's commitments to the British intelligence community mean that playing international tournaments in the Soviet Block was far too risky to national security. So the British chess community were deprived of a potential World Championship candidate and potential grandmaster. His chess contributions were limited to local tournaments and writing chess books - including a memorable book about the legendary Boris Spassky - Bobby Fischer World Championship Match.</p> <p>Alexander showed so much promise in the pre-war years, establishing himself in International tournaments like Nottingham 1936 where he placed respectfully despite having to face 5 World Champions. That promise and intellect was refocused into intelligence work through his experiences in Bletchley Park, so what was robbed from the chess world played a part in keeping Britain safe during the War and the subsequent cold war.</p> <p>Harry Golombek continued being a chess correspondent, and a well recognised one. His book covering the 1948 World Championship Match Tournament is one of many splendid example of chess journalism.</p> <h3>Something to be proud of</h3> <p>I'm immensely proud of all the people who worked in and with Bletchley Park during the War. Every single one of them. I am still aggrieved however that Britain, or Churchill in particular, gave up its leading role in the computer revolution. I understand the political circumstances of the imminent threat of Communist Europe and Cold War threat provoked Churchill into hiding all evidence of the superiority of British Intelligence Services; but each time I see Silicon Valley herald itself as being the dog's bollocks, I wistfully remember that we handed that advantage over to them on a silver plate. And that is the nature of the British Spirit and stoicism.</p> <p>I loved our big geek day out in Bletchley Park. I learnt far more than I imagined. Geekwise I'm satiated. But I know I want to go back and learn more. Thank you to the Bletchley Park staff for making us feel very welcome. Thank you for fighting hard to keep the story of Bletchley Park alive - the story of the British geeks and their phenomenal contribution to protecting our freedoms.</p> <p>Bletchley Park - no movie can do it justice. Not even a blog post can convey just how instrumental they were. And I didn't even mention the working Colossus, the counter-intelligence operations, the pigeons, the D-Day involvement, the unheeded warnings, the Lorenz cipher, the Harrier Jumpjet, the amazing private tour we had, Alan Turing, the Computer History museum, the Churchill museum, the cipher museum... so much.</p>]]></content:encoded>
      </item>
      <item>
         <title>Installing CouchDB on Jeos 8.04</title>
         <link>http://www.isolani.co.uk/blog/web/InstallingCouchdbOnJeos804</link>
         <guid isPermaLink="false">gg6L8PuW3BGXJwFvjtzu1g_2f909f6fda2f4668a2ac7d4131529445</guid>
         <pubDate>Sun, 29 Nov 2009 20:09:07 -0800</pubDate>
         <content:encoded><![CDATA[<p>JEOS (Just Enough Operating System) is a wonderful baseline for creating Linux-based virtual machines for web development. Bradley Wright has written up the best set of instructions for <a rel="nofollow" target="_blank" href="http://intranation.com/entries/2009/03/development-virtual-machines-os-x-using-vmware-and/">creating a new virtual machine for web development</a> running on JEOS and that is the starting point for building a CouchDB server.</p>
<p>With a bare-bones server up and running it's time to install CouchDB. CouchDB is available as an apt install on Ubuntu 8.10 and above, but it won't be the cutting edge code and so some features may be missing. So I had no choice but to go for the tar.gz install. But first, we can install the package dependencies:</p>
<ul>
<li><kbd>sudo apt-get install automake autoconf libtool subversion-tools help2man</kbd></li>
<li><kbd>sudo apt-get install build-essential erlang libicu38 libicu-dev</kbd></li>
<li><kbd>sudo apt-get install libreadline5-dev checkinstall libmozjs-dev wget</kbd></li>
<li><kbd>sudo apt-get install libcurl4-gnutls-dev</kbd></li>
</ul>
<p>Next we need to get Erlang 5.6 or above. This is another case where newer releases of Ubuntu have this version, but not Ubuntu 8.04. But this time the Apache folks on the CouchDB project have a nifty <a rel="nofollow" target="_blank" href="http://wiki.apache.org/couchdb/Error_messages#Erlang-version-less-5.6.0">solution of using the Ubuntu Intrepid repository</a> to grab the updated version of Erlang. (Chris Strom's blog post <a rel="nofollow" target="_blank" href="http://japhr.blogspot.com/2009/03/yak-shaving-is-new-dependency-hell.html">Yak Shaving is the new Dependency Hell</a> help deal with a number of dependency issues thrown up by configure)</p>
<p>That's all the dependencies sorted. Now onto downloading the most up-to-date CouchDB source code and building it (this follows the <a rel="nofollow" target="_blank" href="http://barkingiguana.com/blog/2008/06/28/installing-couchdb-080-on-ubuntu-804/">approach documented by Craig R Webster</a>) :</p>
<ul>
<li><kbd>wget http://mirror.public-internet.co.uk/ftp/apache/couchdb/0.9.1/apache-couchdb-0.9.1.tar.gz</kbd></li>
<li><kbd>tar -xzvf apache-couchdb-0.9.1.tar.gz</kbd></li>
<li><kbd>cd apache-couchdb-0.9.1</kbd></li>
<li><kbd>./configure</kbd></li>
<li><kbd>make &amp;&amp; sudo make install</kbd></li>
</ul>
<p>At this point we have a working installed version of CouchDB. Craig continues with some additional work, and even gets couchdb installed as a service that can be started and stopped using the bog-standard Ubuntu init.d methods:</p>
<ul>
<li><kbd>sudo adduser couchdb</kbd></li>
<li><kbd>sudo mkdir -p /usr/local/var/lib/couchdb</kbd></li>
<li><kbd>sudo chown -R couchdb /usr/local/var/lib/couchdb</kbd></li>
<li><kbd>sudo mkdir -p /usr/local/var/log/couchdb</kbd></li>
<li><kbd>sudo chown -R couchdb /usr/local/var/log/couchdb</kbd></li>
<li><kbd>sudo mkdir -p /usr/local/var/run</kbd></li>
<li><kbd>sudo chown -R couchdb /usr/local/var/run</kbd></li>
<li><kbd>sudo cp /usr/local/etc/init.d/couchdb /etc/init.d/</kbd></li>
<li><kbd>sudo update-rc.d couchdb defaults</kbd></li>
<li><kbd>sudo /etc/init.d/couchdb start</kbd></li>
</ul>
<p>At this point CouchDB is running as a daemon. And we can test it via HTTP by calling the root URL on localhost:</p>
<ul>
<li><kbd>wget http://localhost:5984/</kbd></li>
</ul>
<p>Wget saves the contents of this url into index.html, and this contains:</p>
<pre><code>{"couchdb":"Welcome","version":"0.9.1"}</code></pre>
<p>And we are done!</p> <h3>Related links</h3>
<ul> <li><a rel="nofollow" target="_blank" href="http://nefariousdesigns.co.uk/archive/2009/07/couchdb-on-an-ubuntu-development-vm/">Tim Huegdon: CouchDB on an Ubuntu Development VM</a> takes us through installing the Ubuntu supplied CouchDB package. Easier install if you don't mind running CouchDB 0.80.</li>
</ul>]]></content:encoded>
      </item>
      <item>
         <title>MacSpeech Dictate: First Impressions</title>
         <link>http://feedproxy.google.com/~r/mikewest/~3/r-axoiJVW94/macspeech-dictate-first-impressions</link>
         <description>&lt;p&gt;I suspect that the first thing any developer does when they get their hands on &lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://www.macspeech.com/dictate/&quot;&gt;MacSpeech Dictate&lt;/a&gt; is to begin writing a review of MacSpeech Dictate &lt;em&gt;in&lt;/em&gt; MacSpeech Dictate. I am no exception.&lt;/p&gt; &lt;p&gt;Over the last three months I've develop more pain than usual in my wrists and elbows. It&amp;rsquo;s not been painful enough to stop me from typing altogether, but certainly enough to make me stop and think about the amount of time I spend typing at the computer.&lt;/p&gt; &lt;p&gt;My dad has been playing with Dragon Naturally Speaking on and off for quite some time now, so speech recognition software has been on my radar for years. In fact, I suspect he personally financed the software&amp;rsquo;s research and development over the first few years of its life&amp;hellip; Of course the software was initially more or less worthless, its output was simply miserable through the first few versions. But my dad continued to upgrade. Year after year he picked up a new version of Dragon, installed it, spent hours training at, and eventually began to actually get things done using the software. Now it&amp;rsquo;s my turn.&lt;/p&gt; &lt;p&gt;So, first impressions (beyond the fact that it&amp;rsquo;s simply strange to talk instead of type):&lt;/p&gt; &lt;ol&gt;
&lt;li&gt;&lt;p&gt;I'm a little surprised at the delay between my speech and its recognition. It shouldn&amp;rsquo;t be surprising when considering how much work is involved in this sort of thing, but it is. I speak, and about a second and a half later text appears on the screen. As long as I'm not actually paying attention to the screen, this doesn&amp;rsquo;t bother me at all. At the moment, however, I'm paying quite a bit of attention to the screen, so it&amp;rsquo;s a little distracting.&lt;/p&gt; &lt;p&gt;The text is generally correct, so that delay is easy enough to ignore. There is a slider in the preferences that offers a balance between speed and accuracy. I&amp;rsquo;ll play with that later, as I'm interested in the effect it has on the text produced.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;I'm very surprised at the out-of-the-box accuracy. Dictate is doing a much better job than I expected it to, especially given my lack of experience with speech recognition software, and the seemingly insubstantial amount of text used to train the program. I read to it for about 10 minutes total and based on that small amount of training, I'm getting something like 90% accuracy. Reading back over the text that Dictate has produced, I certainly see some issues: it&amp;rsquo;s not perfect by any means. I&amp;rsquo;ll need to go back and edit a few portions, but overall I'm impressed.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;I need to get used to the command structure. Specifically, I need to train myself to pause before and after commands. Dictate will delete the last phrase when I say &amp;ldquo;scratch that,&amp;rdquo; and delete the last word when I say &amp;ldquo;scratch word.&amp;rdquo; If I speak too fluidly, Dictate doesn&amp;rsquo;t recognize &amp;ldquo;scratch that&amp;rdquo; as a command. When I make a mistake I have to remember to pause a moment before correcting myself. That&amp;rsquo;ll take some time to get used to.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Dictate forces me to pay much more attention to the words I choose then I usually do. I normally write very fluidly, editing myself as I go. I&amp;rsquo;ll write half a sentence, jump back to the paragraph before to make a change, delete the sentence I'd started, rewrite the sentence, and start again. That process simply doesn&amp;rsquo;t work with speech recognition software. It&amp;rsquo;s much more difficult to jump around in the document, so it&amp;rsquo;s much more important for me to address a topic more linearly. I have to think before I speak, which is new to me.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt; &lt;p&gt;Overall, I like this. I think it&amp;rsquo;s something I can get used to. It&amp;rsquo;s certainly better on my hands and wrists, and that&amp;rsquo;s something I very much appreciate at the moment. So far, it&amp;rsquo;s looking like a worthwhile purchase. Let&amp;rsquo;s see how I feel about a week or two.&lt;/p&gt; &lt;p&gt;&lt;strong&gt;A note on process:&lt;/strong&gt; I dictated this document via Dictate in a bit more than half an hour, stopping relatively often to figure out exactly what I was doing. I then copied the text out of Dictate&amp;rsquo;s notepad, pasted into a real editor, and cleaned up the text. I'm not thrilled with workflow, but it&amp;rsquo;s not bad. Much less typing, which I'm certainly happy about.&lt;/p&gt; &lt;div class=&quot;feedflare&quot;&gt;
&lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://feeds.feedburner.com/~ff/mikewest?a=r-axoiJVW94:X9PE9ZKaqKI:2mJPEYqXBVI&quot;&gt;&lt;img src=&quot;http://feeds.feedburner.com/~ff/mikewest?d=2mJPEYqXBVI&quot; border=&quot;0&quot;&gt;&lt;/a&gt; &lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://feeds.feedburner.com/~ff/mikewest?a=r-axoiJVW94:X9PE9ZKaqKI:qZ7jBH1wJJ8&quot;&gt;&lt;img src=&quot;http://feeds.feedburner.com/~ff/mikewest?d=qZ7jBH1wJJ8&quot; border=&quot;0&quot;&gt;&lt;/a&gt; &lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://feeds.feedburner.com/~ff/mikewest?a=r-axoiJVW94:X9PE9ZKaqKI:7Q72WNTAKBA&quot;&gt;&lt;img src=&quot;http://feeds.feedburner.com/~ff/mikewest?d=7Q72WNTAKBA&quot; border=&quot;0&quot;&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src=&quot;http://feeds.feedburner.com/~r/mikewest/~4/r-axoiJVW94&quot; height=&quot;1&quot; width=&quot;1&quot;/&gt;</description>
         <guid isPermaLink="false">http://mikewest.org/2009/11/macspeech-dictate-first-impressions</guid>
         <pubDate>Wed, 18 Nov 2009 16:00:00 -0800</pubDate>
      </item>
      <item>
         <title>My Jekyll Fork</title>
         <link>http://feedproxy.google.com/~r/mikewest/~3/ac4QnQuHRGQ/my-jekyll-fork</link>
         <description>&lt;p&gt;&lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://jekyllrb.com/&quot;&gt;Jekyll&lt;/a&gt; is an interesting project, a well-architected throwback to a time before unnecessary dynamism reigned supreme. In contrast to blog engines like Wordpress or Textile, Jekyll doesn&amp;rsquo;t attempt to do anything other than push raw content through a few simple filters out into the world in the form of static HTML files. Jekyll&amp;rsquo;s &lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://tom.preston-werner.com/2008/11/17/blogging-like-a-hacker.html&quot;&gt;publication philosophy&lt;/a&gt; is very much in line with my own, and I appreciate the work that&amp;rsquo;s gone into it. It&amp;rsquo;s relatively widely used, and therefore much more stable and well-tested than anything I'd write on my own. Given my &lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://twitter.com/mikewest/status/4605321990&quot;&gt;recent experience&lt;/a&gt;, I want something that will Just Work™, and this looks like it. I finished moving this site to Jekyll yesterday, and I'm quite happy with how it&amp;rsquo;s working&amp;hellip;&lt;/p&gt; &lt;p&gt;It doesn&amp;rsquo;t fit me perfectly, though. Here, I&amp;rsquo;ll point to a few features that I think are missing, and a few design decisions that I think are worth reconsideration. Happily, it&amp;rsquo;s an open source project, so I&amp;rsquo;ll also be able to point to my fork of the project where I'm busy addressing these shortcomings.&lt;/p&gt; &lt;h2&gt;&amp;ldquo;Generated&amp;rdquo; Pages: Tags and Archives&lt;/h2&gt; &lt;p&gt;The biggest gap I see in Jekyll&amp;rsquo;s feature set is support for &amp;ldquo;generated&amp;rdquo; pages (covered in &lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://github.com/mojombo/jekyll/issues#issue/16&quot;&gt;Issue #16&lt;/a&gt;). HTML that Jekyll produces is tied one-to-one with files you create on the filesystem. This has the appeal of simplicity, fails in a number of ways to support two quasi-dynamic things that I consider essential to the kind of sites Jekyll aims to produce: tags, and archives.&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Tags&lt;/strong&gt; are a nice way of grouping content on a site, and surfacing that content to readers in an unobtrusive way. Jekyll, out of the box, does a miserable job of making them available in templates. &lt;code&gt;site.tags&lt;/code&gt; gives you a list of &lt;em&gt;all&lt;/em&gt; the site&amp;rsquo;s tags, &lt;code&gt;page.tags&lt;/code&gt; gives you the tags for the current page, and that&amp;rsquo;s it. That&amp;rsquo;s simply not enough structured data to do anything useful with; I want more. &amp;ldquo;More&amp;rdquo;, in my case, meaning two things: a separate page for each tag at &lt;code&gt;/tags/[TAG]&lt;/code&gt;, listing each article that fits; and a page listing out all the tags on the site (in cloud form, if only because I'm &lt;em&gt;so&lt;/em&gt; Web 2.0). The latter is (painfully) possible out of the box, the former is not.&lt;/p&gt; &lt;p&gt;My solution (based heavily on &lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://matflores.com/&quot;&gt;Matt Flores&lt;/a&gt;&amp;lsquo; &lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://github.com/matflores/jekyll/commit/abd0491c451b77bd119a0071457a362c35e6c2f6&quot;&gt;fork&lt;/a&gt;) is available in the &lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://github.com/mikewest/jekyll/tree/tag_index&quot;&gt;tag_index branch&lt;/a&gt; of my Jekyll fork. The implementation is very low-impact: simply add a &lt;code&gt;tag_detail.html&lt;/code&gt; layout to your site&amp;rsquo;s &lt;code&gt;_layouts&lt;/code&gt; directory. Jekyll will auto-generate pages using that layout for each tag on your site, providing &lt;code&gt;page.tag&lt;/code&gt; as a variable inside each as they&amp;rsquo;re rendered. This allows you to dive into &lt;code&gt;site.tags&lt;/code&gt; to pull out lists of articles in a very straightforward way. Once rendered into HTML, the result is placed into a directory you specify via a configuration variable (&lt;code&gt;tag_root&lt;/code&gt;). This has worked brilliantly for me here on this site.&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Archive pages&lt;/strong&gt; listing out content written during a certain period are another nice way of dividing up posts on a site. Especially useful for sites with more than a few posts, it&amp;rsquo;s a mechanism for showing users posts that fit together temporally. It&amp;rsquo;s nice to be able to see &lt;a rel=&quot;nofollow&quot;&gt;all of 2007&amp;rsquo;s posts&lt;/a&gt;, for instance. Or &lt;a rel=&quot;nofollow&quot;&gt;all posts from November of 2008&lt;/a&gt;.&lt;br/&gt;
&lt;/p&gt; &lt;p&gt;Again, I borrowed a bit of code from Matt Flores, brought it up to date with the latest Jekyll tag (0.5.4 at the time I'm writing this), and check it into the &lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://github.com/mikewest/jekyll/tree/archive&quot;&gt;archive branch&lt;/a&gt; of my fork. Similarly to the tagging system above, archives depend on adding a few extra layouts. &lt;code&gt;archive_yearly.html&lt;/code&gt;, &lt;code&gt;archive_monthly.html&lt;/code&gt;, and &lt;code&gt;archive_daily.html&lt;/code&gt; are supported, and offer &lt;code&gt;page.year&lt;/code&gt;, &lt;code&gt;page.month&lt;/code&gt;, and &lt;code&gt;page.day&lt;/code&gt;, which can be used to reference posts in &lt;code&gt;site.collated_posts&lt;/code&gt;. My &lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://github.com/mikewest/mikewest.org/blob/master/_layouts/archive_monthly.html&quot;&gt;&lt;code&gt;archive_monthly.html&lt;/code&gt;&lt;/a&gt; is indicative of how this can work.&lt;/p&gt; &lt;p&gt;Generated pages are written to &lt;code&gt;/[YEAR]/index.html&lt;/code&gt;, &lt;code&gt;/[YEAR]/[MONTH]/index.html&lt;/code&gt;, and &lt;code&gt;/[YEAR]/[MONTH]/[DAY]/index.html&lt;/code&gt; if posts exist over the specified time period.&lt;/p&gt; &lt;h2&gt;Filters&lt;/h2&gt; &lt;p&gt;Jekyll uses the &lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://www.liquidmarkup.org/&quot;&gt;Liquid&lt;/a&gt; templating engine, which isn&amp;rsquo;t exactly my first choice. It&amp;rsquo;s a solid engine, as far as it goes, but it&amp;rsquo;s no &lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://jinja.pocoo.org/2/&quot;&gt;Jinja2&lt;/a&gt;. Regardless, Jekyll has built in a number of useful filters that can be used to perform operations on text before it&amp;rsquo;s rendered. &lt;code&gt;textilize()&lt;/code&gt; is a good example of this, running text through a Textile parser, then writing the output instead of the original text. It&amp;rsquo;s great!&lt;/p&gt; &lt;p&gt;Except, of course, for the fact that Textile is hideous. :) I much prefer to write Markdown formatted text (it&amp;rsquo;s just easier for me to read, really), so I was a bit miffed when I discovered that a Markdown counterpart to &lt;code&gt;textilize()&lt;/code&gt; was simply missing.&lt;/p&gt; &lt;p&gt;A more robust system is being discussed (slowly) in &lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://github.com/mojombo/jekyll/issues#issue/19&quot;&gt;Issue #19&lt;/a&gt;. I decided not to wait for a perfect solution, and simply added &lt;code&gt;markdownize()&lt;/code&gt; in the &lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://github.com/mikewest/jekyll/tree/filters&quot;&gt;filters branch&lt;/a&gt; of my fork. A trivial, but &lt;em&gt;very&lt;/em&gt; necessary change.&lt;/p&gt; &lt;h2&gt;Default Configuration Values&lt;/h2&gt; &lt;p&gt;I really like the way that Jekyll expects posts to be formatted. Each post lives in it&amp;rsquo;s own file, and each file begins with a YAML block specifying metadata such as titles, teasers, and layout style. This allows you to configure each post separately, and lends quite a bit of flexibility to the end product.&lt;/p&gt; &lt;p&gt;As &lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://github.com/mojombo/jekyll/issues#issue/19&quot;&gt;Issue #25&lt;/a&gt; points out, it'd be nice if layout in particular could be specified at the site level as a default value. Posts that need different layouts are (generally) few and far between, and a global configuration would make the most common case a bit simpler.&lt;/p&gt; &lt;p&gt;Henrik &lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://github.com/henrik/jekyll/commit/77bf31c42c25c2f87c215348a816b730104fe820&quot;&gt;took a stab at a solution&lt;/a&gt; to the problem, which I ran off with and improved upon in the &lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://github.com/mikewest/jekyll/tree/post_defaults&quot;&gt;post_defaults branch&lt;/a&gt; of my fork. I'm waiting on someone to take a look at this work now, but I'm not holding my breath for it to be merged into the official release.&lt;/p&gt; &lt;h2&gt;Problematic Design&lt;/h2&gt; &lt;p&gt;Beyond gaps in the feature set, Jekyll does one or two things that I simply disagree with.&lt;/p&gt; &lt;p&gt;Jekyll tightly couples content and layout by assuming that both will exist together in a defined directory structure. Leaving a bit of complexity to the side, a typical Jekyll site contains a &lt;code&gt;_posts&lt;/code&gt; subdirectory filled to the brim with lovely raw content, and a &lt;code&gt;_layouts&lt;/code&gt; directory filled with &lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://www.liquidmarkup.org/&quot;&gt;Liquid&lt;/a&gt;-based HTML templates. The former is exclusively concerned with content, the latter exclusively with layout.&lt;/p&gt; &lt;p&gt;For the same reasons that we eventually started building websites without inline style information, separating the concerns of the site&amp;rsquo;s semantics from it&amp;rsquo;s layout and behavior, I don&amp;rsquo;t believe that these bits belong in the same repository. At a minimum, I'd like to be able to deploy a version of my website&amp;rsquo;s look and feel without worrying about whether or not I tagged the release before or after adding a post. The one activity has nothing to do with the other, and both ought be able to proceed in parallel. Jekyll&amp;rsquo;s current implementation encourages mixing the two, which I don&amp;rsquo;t appreciate. Instead, I prefer to run two distinct repositories: one containing &lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://github.com/mikewest/mgc/&quot;&gt;pure content&lt;/a&gt;, the other containing &lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://github.com/mikewest/mikewest.org/&quot;&gt;site-specific layout and configuration&lt;/a&gt;. This feels cleaner to me.&lt;/p&gt; &lt;p&gt;The solution I've hacked together is available in the &lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://github.com/mikewest/jekyll/tree/contentpath&quot;&gt;contentpath branch&lt;/a&gt; of my Jekyll fork. I've added a single configuration variable (&lt;code&gt;content_root&lt;/code&gt;) that contains an absolute path to the directory containing the site&amp;rsquo;s content. That directory will be parsed in it&amp;rsquo;s entirety (e.g. no &lt;code&gt;_posts&lt;/code&gt; subdirectory is required). If a &lt;code&gt;_posts&lt;/code&gt; directory exists in the usual location (&lt;code&gt;[SITE_ROOT]/_posts/&lt;/code&gt;) it will be parsed as well to ensure backwards compatibility.&lt;br/&gt;
&lt;/p&gt; &lt;p&gt;I don&amp;rsquo;t expect this change to make it into the main tree, as it&amp;rsquo;s probably not interesting for Jekyll&amp;rsquo;s main audience of GitHub Pages users who &lt;em&gt;do&lt;/em&gt; in fact very much want to deal with a single repository. Moreover, when dealing with potentially malicious users, it&amp;rsquo;s not a brilliant idea to give them the ability to generate publicly accessible pages from &lt;em&gt;any&lt;/em&gt; readable directory on a system. For my use, however, it&amp;rsquo;s more or less perfect, and I&amp;rsquo;ll do my best to keep it rebased on top of the latest Jekyll tags for anyone else who&amp;rsquo;s of the same mind.&lt;/p&gt; &lt;div class=&quot;feedflare&quot;&gt;
&lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://feeds.feedburner.com/~ff/mikewest?a=ac4QnQuHRGQ:w-56tocEeYo:2mJPEYqXBVI&quot;&gt;&lt;img src=&quot;http://feeds.feedburner.com/~ff/mikewest?d=2mJPEYqXBVI&quot; border=&quot;0&quot;&gt;&lt;/a&gt; &lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://feeds.feedburner.com/~ff/mikewest?a=ac4QnQuHRGQ:w-56tocEeYo:qZ7jBH1wJJ8&quot;&gt;&lt;img src=&quot;http://feeds.feedburner.com/~ff/mikewest?d=qZ7jBH1wJJ8&quot; border=&quot;0&quot;&gt;&lt;/a&gt; &lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://feeds.feedburner.com/~ff/mikewest?a=ac4QnQuHRGQ:w-56tocEeYo:7Q72WNTAKBA&quot;&gt;&lt;img src=&quot;http://feeds.feedburner.com/~ff/mikewest?d=7Q72WNTAKBA&quot; border=&quot;0&quot;&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src=&quot;http://feeds.feedburner.com/~r/mikewest/~4/ac4QnQuHRGQ&quot; height=&quot;1&quot; width=&quot;1&quot;/&gt;</description>
         <guid isPermaLink="false">http://mikewest.org/2009/11/my-jekyll-fork</guid>
         <pubDate>Wed, 11 Nov 2009 16:00:00 -0800</pubDate>
      </item>
      <item>
         <title>Fallow fields, revisited</title>
         <link>http://feedproxy.google.com/~r/mikewest/~3/116QoaYj9io/fallow-fields-revisited</link>
         <description>&lt;p&gt;I'm currently in the process of gutting my website, and rebuilding it piece by piece. I suspect I'm doing this to distract myself from the fact that I don&amp;rsquo;t seem to have anything interesting floating around in my head to write about. &amp;ldquo;Surely it&amp;rsquo;s the &lt;em&gt;site&amp;rsquo;s&lt;/em&gt; fault; raze it to the ground!&amp;rdquo;, the large, simple, and shouty part of my brain tells me. So I build anew (this is possibly &lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://mikewest.org/2009/09/productivity-or-my-lack-thereof&quot;&gt;ironic&lt;/a&gt;, but I'm ignoring that).&lt;/p&gt; &lt;p&gt;Happily, the small, quiet, and generally reasonable portion of my brain agrees with the plan, at least insofar as it&amp;rsquo;s clear that the current system (&lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://github.com/mikewest/fallow/&quot;&gt;fallow&lt;/a&gt;) was a solid idea but poorly implemented. The system works, and I'm happy I wrote it. It was a good introduction to Ruby and Git, and a good reason to migrate off the almost-as-inefficient-as-wordpress Textpattern. But it&amp;rsquo;s failing me in a number of ways, the most important being that I literally forgot how to get content onto the site, and it took me 45 minutes of reading through painfully structured Ruby code to figure it out again. That&amp;rsquo;s the sort of thing that happens when you don&amp;rsquo;t touch a website for 6 months.&lt;/p&gt; &lt;p&gt;Rather that catalog the failings of the system I'm replacing (for they are legion), I'd like to touch on the carefully considered bits I'm keeping:&lt;/p&gt; &lt;ul&gt;
&lt;li&gt;&lt;p&gt;URL structure: Posts live at &lt;code&gt;/[year]/[month]/[URLified Title]&lt;/code&gt; which
seems more or less perfect to me. It&amp;rsquo;s meaningful, while containing just
enough temporal context to make completely outdated information easy to
spot. Moreover, it provides a natural &lt;code&gt;/[year]/&lt;/code&gt; and &lt;code&gt;/[year]/[month]/&lt;/code&gt;
for yearly and monthly archive pages. Tag pages live under &lt;code&gt;/tags/[tag]&lt;/code&gt;,
which makes sense, and ad hoc pages have ad hoc URLs (&lt;code&gt;/is/&lt;/code&gt;, for instance).
This strikes me as a clean setup, one which I can&amp;rsquo;t see any way to improve
upon.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Content storage: The site&amp;rsquo;s content consists entirely of UTF-8 encoded text
files on disk. Text files are simple to work with, and have a more or less
infinite shelf life. A site like this one simply doesn&amp;rsquo;t need a database,
a single flat text file per piece of content is &lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://mnmlist.com/a-case-for-storing-all-your-info-in-text-files/&quot;&gt;good enough&lt;/a&gt;. Metadata
(title, tags, etc.) is contained in a YAML block at the top of each file.
It&amp;rsquo;s a format that is clear, human readable, and easily parsed, and I'm
especially pleased to see that the format I'd decided upon for Fallow
matches up quite well against more widely used systems like &lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://jekyllrb.com/&quot;&gt;Jekyll&lt;/a&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Static HTML: Dynamic content doesn&amp;rsquo;t really exist on this site. I write an
article, then post it online. That&amp;rsquo;s the extent of the processing that
particular page needs. The server shouldn&amp;rsquo;t be working to rebuild an
article from last week (or last year!) every time it&amp;rsquo;s requested, that&amp;rsquo;s
simply wasteful. This site, therefore, generates a page once when it&amp;rsquo;s
created, or when a template changes, and then simply serves that cached copy
over and over again. Similarly, overview pages (like tag pages, or current
archives) are regenerated when a new article is published, then served
straight from disk. On a small VPS, I can serve upwards of 300 static
requests per second through Nginx with extremely low load. Textpattern
would fall over and die at those absurd traffic levels.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Historical redirects: The (miserable) &lt;code&gt;/blog/id/[ID]&lt;/code&gt; URL structure I
decided upon in 2005 still works for the content I've kept from that period.
The (also bad) &lt;code&gt;/archives/[Title]/&lt;/code&gt; structure from 2007-8 works too. The
(not so lovely) Tumblr-generated links for content that used to be at
&lt;code&gt;blog.mikewest.org&lt;/code&gt; will redirect nicely. All these old URLs will continue
to generate nice, clean permanent redirects
&lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://www.w3.org/Provider/Style/URI&quot;&gt;for the foreseeable future&lt;/a&gt;: why make the reader jump through hoops
created by my lack of foresight?&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt; &lt;p&gt;So, those are the good bits I'd like to keep going as I rebuild. With the understanding that I'm about to make one of those dangerous &amp;ldquo;forward looking statements&amp;rdquo; that I never seem to follow through on as cleanly as I'd like, I expect &lt;code&gt;mikewest.org&lt;/code&gt; to be running a new Jekyll-based backend sometime in October. With luck, no one will notice a thing but me. With even more luck, I&amp;rsquo;ll squeeze out a post or two about the bits of Jekyll I'm adjusting, and the places where it&amp;rsquo;s falling down completely.&lt;/p&gt; &lt;div class=&quot;feedflare&quot;&gt;
&lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://feeds.feedburner.com/~ff/mikewest?a=116QoaYj9io:vW-gBOIiHBc:2mJPEYqXBVI&quot;&gt;&lt;img src=&quot;http://feeds.feedburner.com/~ff/mikewest?d=2mJPEYqXBVI&quot; border=&quot;0&quot;&gt;&lt;/a&gt; &lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://feeds.feedburner.com/~ff/mikewest?a=116QoaYj9io:vW-gBOIiHBc:qZ7jBH1wJJ8&quot;&gt;&lt;img src=&quot;http://feeds.feedburner.com/~ff/mikewest?d=qZ7jBH1wJJ8&quot; border=&quot;0&quot;&gt;&lt;/a&gt; &lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://feeds.feedburner.com/~ff/mikewest?a=116QoaYj9io:vW-gBOIiHBc:7Q72WNTAKBA&quot;&gt;&lt;img src=&quot;http://feeds.feedburner.com/~ff/mikewest?d=7Q72WNTAKBA&quot; border=&quot;0&quot;&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src=&quot;http://feeds.feedburner.com/~r/mikewest/~4/116QoaYj9io&quot; height=&quot;1&quot; width=&quot;1&quot;/&gt;</description>
         <guid isPermaLink="false">http://mikewest.org/2009/10/fallow-fields-revisited</guid>
         <pubDate>Sat, 03 Oct 2009 17:00:00 -0700</pubDate>
      </item>
      <item>
         <title>Productivity Or My Lack Thereof</title>
         <link>http://feedproxy.google.com/~r/mikewest/~3/0IS5ewDHGIg/productivity-or-my-lack-thereof</link>
         <description>&lt;p&gt;I just spent the last half-hour screwing around with my Vim configuration to set up a &amp;ldquo;more perfect&amp;rdquo; writing environment. Fullscreen! Eighty columns! Proper line-wrapping! Large, readable font! Markdown syntax highlighting! Spellcheck! Etcetera, etcetera! Hilariously wrongheaded, of course, since I created this environment &lt;em&gt;instead of&lt;/em&gt; writing anything. Likewise, I've played around with &lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://todotxt.com/&quot;&gt;todo.sh&lt;/a&gt; quite a bit in the last week or two (it&amp;rsquo;s nice), trying to put together a good system for recording my ever-growing list of things I need to take care of. Perhaps there&amp;rsquo;s a reason that the list is ever-growing.&lt;/p&gt; &lt;p&gt;Building new bash scripts that make recording tasks easier might &lt;em&gt;feel&lt;/em&gt; like Doing Important Work, but it isn&amp;rsquo;t. Not really. This is unfortunately true even when &amp;ldquo;write new bash scripts to make recording tasks easier&amp;rdquo; is on my newly created todo list.&lt;/p&gt; &lt;p&gt;This is a long way of saying that &lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://www.marco.org/about&quot;&gt;Marco Arment&lt;/a&gt; is &lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://www.marco.org/182893582&quot;&gt;dead on&lt;/a&gt;:&lt;/p&gt; &lt;blockquote&gt;&lt;p&gt; The best way to increase your productivity, hack your life, and be minimalist is to stop reading those sites.&lt;/p&gt;&lt;/blockquote&gt; &lt;p&gt;Also, hello Internet. It&amp;rsquo;s been a while.&lt;/p&gt; &lt;div class=&quot;feedflare&quot;&gt;
&lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://feeds.feedburner.com/~ff/mikewest?a=0IS5ewDHGIg:uSWlZLnJ6a0:2mJPEYqXBVI&quot;&gt;&lt;img src=&quot;http://feeds.feedburner.com/~ff/mikewest?d=2mJPEYqXBVI&quot; border=&quot;0&quot;&gt;&lt;/a&gt; &lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://feeds.feedburner.com/~ff/mikewest?a=0IS5ewDHGIg:uSWlZLnJ6a0:qZ7jBH1wJJ8&quot;&gt;&lt;img src=&quot;http://feeds.feedburner.com/~ff/mikewest?d=qZ7jBH1wJJ8&quot; border=&quot;0&quot;&gt;&lt;/a&gt; &lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://feeds.feedburner.com/~ff/mikewest?a=0IS5ewDHGIg:uSWlZLnJ6a0:7Q72WNTAKBA&quot;&gt;&lt;img src=&quot;http://feeds.feedburner.com/~ff/mikewest?d=7Q72WNTAKBA&quot; border=&quot;0&quot;&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src=&quot;http://feeds.feedburner.com/~r/mikewest/~4/0IS5ewDHGIg&quot; height=&quot;1&quot; width=&quot;1&quot;/&gt;</description>
         <guid isPermaLink="false">http://mikewest.org/2009/09/productivity-or-my-lack-thereof</guid>
         <pubDate>Tue, 22 Sep 2009 17:00:00 -0700</pubDate>
      </item>
      <item>
         <title>Mnot's Redbot</title>
         <link>http://feedproxy.google.com/~r/mikewest/~3/NXacJNm5RaA/mnots-redbot</link>
         <description>&lt;p&gt;&lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://www.mnot.net/&quot;&gt;Mark Nottingham&lt;/a&gt; has put together a really useful tool that aids in the analysis of the behavior of HTTP resources. Visit &lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://redbot.org/&quot;&gt;http://redbot.org/&lt;/a&gt;, type in a web address, and Redbot will report the resource&amp;rsquo;s cachability based on the returned headers, and provide a helpful list of recommendations for improvement.&lt;/p&gt; &lt;p&gt;Running it on &lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://mikewest.org/&quot;&gt;http://mikewest.org/&lt;/a&gt;, for instance, &lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://redbot.org/?uri=http%3A%2F%2Fwww.mikewest.org%2F&quot;&gt;flags the fact&lt;/a&gt; that I compress the response if the browser tells me that it can accept compressed content, but that I've neglected to send the proper &lt;code&gt;Vary&lt;/code&gt; header to let caches know that the response needs to be negotiated, and cached based on the &lt;code&gt;Accept-Encoding&lt;/code&gt; request header. This is &lt;em&gt;useful&lt;/em&gt;, especially for &lt;em&gt;actual&lt;/em&gt; applications for which it might matter.&lt;/p&gt; &lt;p&gt;So useful, in fact, that I'm forking it to submit some patches. Mark&amp;rsquo;s put the Redbot code up on GitHub (&lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://github.com/mnot/redbot/tree/master&quot;&gt;mnot/redbot&lt;/a&gt;), and I've started putting together a &lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://github.com/mikewest/redbot/blob/master/src/redbotcli.py&quot;&gt;command line version&lt;/a&gt; based on the web version he&amp;rsquo;s built.&lt;/p&gt; &lt;p&gt;I've mentioned that &lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://mikewest.org/2008/11/i-love-github&quot;&gt;I love GitHub&lt;/a&gt;, right? This is exactly why. :)&lt;/p&gt; &lt;div class=&quot;feedflare&quot;&gt;
&lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://feeds.feedburner.com/~ff/mikewest?a=NXacJNm5RaA:jhqxwuAgN2A:2mJPEYqXBVI&quot;&gt;&lt;img src=&quot;http://feeds.feedburner.com/~ff/mikewest?d=2mJPEYqXBVI&quot; border=&quot;0&quot;&gt;&lt;/a&gt; &lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://feeds.feedburner.com/~ff/mikewest?a=NXacJNm5RaA:jhqxwuAgN2A:qZ7jBH1wJJ8&quot;&gt;&lt;img src=&quot;http://feeds.feedburner.com/~ff/mikewest?d=qZ7jBH1wJJ8&quot; border=&quot;0&quot;&gt;&lt;/a&gt; &lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://feeds.feedburner.com/~ff/mikewest?a=NXacJNm5RaA:jhqxwuAgN2A:7Q72WNTAKBA&quot;&gt;&lt;img src=&quot;http://feeds.feedburner.com/~ff/mikewest?d=7Q72WNTAKBA&quot; border=&quot;0&quot;&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src=&quot;http://feeds.feedburner.com/~r/mikewest/~4/NXacJNm5RaA&quot; height=&quot;1&quot; width=&quot;1&quot;/&gt;</description>
         <guid isPermaLink="false">http://mikewest.org/2009/05/mnots-redbot</guid>
         <pubDate>Fri, 22 May 2009 17:00:00 -0700</pubDate>
      </item>
      <item>
         <title>Playing with Placemaker</title>
         <link>http://feedproxy.google.com/~r/mikewest/~3/rzeMzpFeZm8/playing-with-placemaker</link>
         <description>&lt;p&gt;Yahoo&amp;rsquo;s latest API is really quite cool: &lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://developer.yahoo.com/geo/placemaker/guide/&quot;&gt;Placemaker&lt;/a&gt; takes your unstructured data (e.g. any HTML page, RSS feed, etc), and extracts a nice list of &lt;em&gt;locations&lt;/em&gt; that your data refers to. It&amp;rsquo;s a brilliant tool, and I can think of quite a few ways I'd like to use it in the future. Along with their release of a &lt;em&gt;ton&lt;/em&gt; of &lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://developer.yahoo.com/geo/geoplanet/data/&quot;&gt;WhereOnEarth ID codes&lt;/a&gt; that allows you to make use of Yahoo&amp;rsquo;s various geo-services, this is a really good day to play with geocoding unstructured data.&lt;/p&gt; &lt;p&gt;So, let&amp;rsquo;s play:&lt;/p&gt; &lt;p&gt;Accessing Placemaker is simple: assuming that you've somehow managed to &lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://developer.yahoo.com/wsregapp/&quot;&gt;obtain an application id&lt;/a&gt;, you simply make an HTTP &lt;code&gt;POST&lt;/code&gt; request to Yahoo!&amp;rsquo;s Placemaker endpoint with a tiny bit of data specifying the nature of the data you&amp;rsquo;re dealing with, and it&amp;rsquo;s URL. If you like &lt;code&gt;curl&lt;/code&gt; on the command line, this might look like:&lt;/p&gt; &lt;pre&gt;&lt;code&gt;curl -d 'inputLanguage=en-US&amp;amp;documentType=text/html&amp;amp;documentURL=http://mikewest.org/&amp;amp;appid=[APPID]' http://wherein.yahooapis.com/v1/document
&lt;/code&gt;&lt;/pre&gt; &lt;p&gt;You&amp;rsquo;ll get back an XML document (RSS is also available as a response format). Digging into the contents yields:&lt;/p&gt; &lt;ul&gt;
&lt;li&gt;&lt;p&gt;Boilerplate:&lt;/p&gt; &lt;pre&gt;&lt;code&gt;&amp;lt;?xml version=&quot;1.0&quot; encoding=&quot;utf-8&quot;?&amp;gt;
&amp;lt;contentlocation xmlns:yahoo=&quot;http://www.yahooapis.com/v1/base.rng&quot; xmlns=&quot;http://wherein.yahooapis.com/v1/schema&quot; xml:lang=&quot;de-DE&quot;&amp;gt; &amp;lt;processingTime&amp;gt;0.380778&amp;lt;/processingTime&amp;gt; &amp;lt;version&amp;gt; build 090508&amp;lt;/version&amp;gt; &amp;lt;documentLength&amp;gt;15906&amp;lt;/documentLength&amp;gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;A (list of) document element(s) containing the extracted locations:&lt;/p&gt; &lt;pre&gt;&lt;code&gt; &amp;lt;document&amp;gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;A best guess at the document&amp;rsquo;s &amp;ldquo;scope&amp;rdquo; (the smallest region that &amp;ldquo;best
describes&amp;rdquo; the document):&lt;/p&gt; &lt;pre&gt;&lt;code&gt; &amp;lt;administrativeScope&amp;gt; &amp;lt;woeId&amp;gt;20071093&amp;lt;/woeId&amp;gt; &amp;lt;type&amp;gt;County&amp;lt;/type&amp;gt; &amp;lt;name&amp;gt;&amp;lt;![CDATA[Munich, Bavaria, DE]]&amp;gt;&amp;lt;/name&amp;gt; &amp;lt;centroid&amp;gt; &amp;lt;latitude&amp;gt;48.1549&amp;lt;/latitude&amp;gt; &amp;lt;longitude&amp;gt;11.5417&amp;lt;/longitude&amp;gt; &amp;lt;/centroid&amp;gt; &amp;lt;/administrativeScope&amp;gt; &amp;lt;geographicScope&amp;gt; &amp;lt;woeId&amp;gt;29388625&amp;lt;/woeId&amp;gt; &amp;lt;type&amp;gt;MMA&amp;lt;/type&amp;gt; &amp;lt;name&amp;gt;&amp;lt;![CDATA[MMA München, Bavaria, DE]]&amp;gt;&amp;lt;/name&amp;gt; &amp;lt;centroid&amp;gt; &amp;lt;latitude&amp;gt;48.1549&amp;lt;/latitude&amp;gt; &amp;lt;longitude&amp;gt;11.5417&amp;lt;/longitude&amp;gt; &amp;lt;/centroid&amp;gt; &amp;lt;/geographicScope&amp;gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Latitude/longitude for a bounding box that contains the places mentioned
in the document (which makes it trivial to draw an &amp;ldquo;area of discussion&amp;rdquo; on
a map):&lt;/p&gt; &lt;pre&gt;&lt;code&gt; &amp;lt;extents&amp;gt; &amp;lt;center&amp;gt; &amp;lt;latitude&amp;gt;48.1364&amp;lt;/latitude&amp;gt; &amp;lt;longitude&amp;gt;11.5775&amp;lt;/longitude&amp;gt; &amp;lt;/center&amp;gt; &amp;lt;southWest&amp;gt; &amp;lt;latitude&amp;gt;48.0417&amp;lt;/latitude&amp;gt; &amp;lt;longitude&amp;gt;11.3771&amp;lt;/longitude&amp;gt; &amp;lt;/southWest&amp;gt; &amp;lt;northEast&amp;gt; &amp;lt;latitude&amp;gt;48.2292&amp;lt;/latitude&amp;gt; &amp;lt;longitude&amp;gt;11.749&amp;lt;/longitude&amp;gt; &amp;lt;/northEast&amp;gt; &amp;lt;/extents&amp;gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Detailed breakdown of the places mentioned in your document, giving you
lat/long coordinates identifying the place&amp;rsquo;s center point. Moreover, it
tells you &lt;em&gt;where&lt;/em&gt; in your document the place was found (string offsets
&lt;em&gt;and&lt;/em&gt; XPath expressions, to each their own). This is helpful for those
occasions when the text you've entered doesn&amp;rsquo;t exactly match the place&amp;rsquo;s
name that Yahoo returns (&amp;ldquo;Munich&amp;rdquo; vs. &amp;ldquo;Munich, Bavaria, DE&amp;rdquo;, in this
example) Annotating your documents with this data should be a piece of
cake.&lt;/p&gt; &lt;pre&gt;&lt;code&gt; &amp;lt;placeDetails&amp;gt; &amp;lt;place&amp;gt; &amp;lt;woeId&amp;gt;676757&amp;lt;/woeId&amp;gt; &amp;lt;type&amp;gt;Town&amp;lt;/type&amp;gt; &amp;lt;name&amp;gt;&amp;lt;![CDATA[Munich, Bavaria, DE]]&amp;gt;&amp;lt;/name&amp;gt; &amp;lt;centroid&amp;gt; &amp;lt;latitude&amp;gt;48.1364&amp;lt;/latitude&amp;gt; &amp;lt;longitude&amp;gt;11.5775&amp;lt;/longitude&amp;gt; &amp;lt;/centroid&amp;gt; &amp;lt;/place&amp;gt; &amp;lt;matchType&amp;gt;0&amp;lt;/matchType&amp;gt; &amp;lt;weight&amp;gt;1&amp;lt;/weight&amp;gt; &amp;lt;confidence&amp;gt;7&amp;lt;/confidence&amp;gt; &amp;lt;/placeDetails&amp;gt; &amp;lt;referenceList&amp;gt; &amp;lt;reference&amp;gt; &amp;lt;woeIds&amp;gt;676757&amp;lt;/woeIds&amp;gt; &amp;lt;start&amp;gt;50&amp;lt;/start&amp;gt; &amp;lt;end&amp;gt;56&amp;lt;/end&amp;gt; &amp;lt;isPlaintextMarker&amp;gt;0&amp;lt;/isPlaintextMarker&amp;gt; &amp;lt;text&amp;gt;&amp;lt;![CDATA[Munich]]&amp;gt;&amp;lt;/text&amp;gt; &amp;lt;type&amp;gt;xpathwithcounts&amp;lt;/type&amp;gt; &amp;lt;xpath&amp;gt;&amp;lt;![CDATA[/html[1]/body[1]/div[2]/div[1]/p[1]]]&amp;gt;&amp;lt;/xpath&amp;gt; &amp;lt;/reference&amp;gt; &amp;lt;/referenceList&amp;gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;And some more boilerplate. :)&lt;/p&gt; &lt;pre&gt;&lt;code&gt; &amp;lt;/document&amp;gt;
&amp;lt;/contentlocation&amp;gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/li&gt;
&lt;/ul&gt; &lt;p&gt;Full documentation of the Placemaker &lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://developer.yahoo.com/geo/placemaker/guide/api_docs.html#query_parameters&quot;&gt;query parameters&lt;/a&gt; and &lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://developer.yahoo.com/geo/placemaker/guide/api-reference.html&quot;&gt;response format&lt;/a&gt; are available on YDN. Christian has put together a demo of a &lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://isithackday.com/hacks/placemaker/&quot;&gt;basic PHP implementation&lt;/a&gt; (though it&amp;rsquo;s XSSable, and shouldn&amp;rsquo;t ever be used in production).&lt;/p&gt; &lt;p&gt;In general, this is &lt;em&gt;brilliant&lt;/em&gt; stuff. I'm looking forward to playing with it!&lt;/p&gt; &lt;div class=&quot;feedflare&quot;&gt;
&lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://feeds.feedburner.com/~ff/mikewest?a=rzeMzpFeZm8:N3lpqWGpYpQ:2mJPEYqXBVI&quot;&gt;&lt;img src=&quot;http://feeds.feedburner.com/~ff/mikewest?d=2mJPEYqXBVI&quot; border=&quot;0&quot;&gt;&lt;/a&gt; &lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://feeds.feedburner.com/~ff/mikewest?a=rzeMzpFeZm8:N3lpqWGpYpQ:qZ7jBH1wJJ8&quot;&gt;&lt;img src=&quot;http://feeds.feedburner.com/~ff/mikewest?d=qZ7jBH1wJJ8&quot; border=&quot;0&quot;&gt;&lt;/a&gt; &lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://feeds.feedburner.com/~ff/mikewest?a=rzeMzpFeZm8:N3lpqWGpYpQ:7Q72WNTAKBA&quot;&gt;&lt;img src=&quot;http://feeds.feedburner.com/~ff/mikewest?d=7Q72WNTAKBA&quot; border=&quot;0&quot;&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src=&quot;http://feeds.feedburner.com/~r/mikewest/~4/rzeMzpFeZm8&quot; height=&quot;1&quot; width=&quot;1&quot;/&gt;</description>
         <guid isPermaLink="false">http://mikewest.org/2009/05/playing-with-placemaker</guid>
         <pubDate>Wed, 20 May 2009 17:00:00 -0700</pubDate>
      </item>
      <item>
         <title>Well. That was easy.</title>
         <link>http://feedproxy.google.com/~r/mikewest/~3/JXcuM1f7Enw/well-that-was-easy</link>
         <description>&lt;p&gt;Getting &lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://blog.mikewest.org/post/108613427/running-python-spidermonkey-on-jeos&quot;&gt;JSLint running inside Spidermonkey&lt;/a&gt; was much simpler than I expected it to be:&lt;/p&gt; &lt;pre&gt;&lt;code&gt;[14:12] src/jslint $ python
Python 2.6.2 (release26-maint, Apr 19 2009, 01:58:18) [GCC 4.3.3] on linux2
Type &quot;help&quot;, &quot;copyright&quot;, &quot;credits&quot; or &quot;license&quot; for more information.
&amp;gt;&amp;gt;&amp;gt; import spidermonkey
&amp;gt;&amp;gt;&amp;gt; rt = spidermonkey.Runtime()
&amp;gt;&amp;gt;&amp;gt; cx = rt.new_context()
&amp;gt;&amp;gt;&amp;gt; text = file( './fulljslint.js' ).read()
&amp;gt;&amp;gt;&amp;gt; cx.execute( text )
u'use strict'
&amp;gt;&amp;gt;&amp;gt; cx.execute( text + 'JSLINT(&quot;i++&quot;, {})' )
False
&amp;gt;&amp;gt;&amp;gt; cx.execute( text + 'JSLINT(&quot;i++&quot;, {}); JSLINT.report();' )
u'&amp;lt;div id=errors&amp;gt;&amp;lt;i&amp;gt;Error:&amp;lt;/i&amp;gt;&amp;lt;p&amp;gt;&amp;lt;i&amp;gt;Implied global:&amp;lt;/i&amp;gt; &amp;lt;code&amp;gt;i&amp;lt;/code&amp;gt;&amp;amp;nbsp;&amp;lt;i&amp;gt;1&amp;lt;/i&amp;gt;&amp;lt;/p&amp;gt;&amp;lt;p&amp;gt;Problem at line 1 character 4: Missing semicolon.&amp;lt;/p&amp;gt;&amp;lt;p class=evidence&amp;gt;i++&amp;lt;/p&amp;gt;&amp;lt;/div&amp;gt;&amp;lt;br&amp;gt;&amp;lt;div id=functions&amp;gt;&amp;lt;div&amp;gt;&amp;lt;i&amp;gt;No new global variables introduced.&amp;lt;/i&amp;gt;&amp;lt;/div&amp;gt;&amp;lt;/div&amp;gt;'
&lt;/code&gt;&lt;/pre&gt; &lt;p&gt;Yay!&lt;/p&gt; &lt;div class=&quot;feedflare&quot;&gt;
&lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://feeds.feedburner.com/~ff/mikewest?a=JXcuM1f7Enw:uMnrCue2I8k:2mJPEYqXBVI&quot;&gt;&lt;img src=&quot;http://feeds.feedburner.com/~ff/mikewest?d=2mJPEYqXBVI&quot; border=&quot;0&quot;&gt;&lt;/a&gt; &lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://feeds.feedburner.com/~ff/mikewest?a=JXcuM1f7Enw:uMnrCue2I8k:qZ7jBH1wJJ8&quot;&gt;&lt;img src=&quot;http://feeds.feedburner.com/~ff/mikewest?d=qZ7jBH1wJJ8&quot; border=&quot;0&quot;&gt;&lt;/a&gt; &lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://feeds.feedburner.com/~ff/mikewest?a=JXcuM1f7Enw:uMnrCue2I8k:7Q72WNTAKBA&quot;&gt;&lt;img src=&quot;http://feeds.feedburner.com/~ff/mikewest?d=7Q72WNTAKBA&quot; border=&quot;0&quot;&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src=&quot;http://feeds.feedburner.com/~r/mikewest/~4/JXcuM1f7Enw&quot; height=&quot;1&quot; width=&quot;1&quot;/&gt;</description>
         <guid isPermaLink="false">http://mikewest.org/2009/05/well-that-was-easy</guid>
         <pubDate>Fri, 15 May 2009 17:00:00 -0700</pubDate>
      </item>
      <item>
         <title>Running `python-spidermonkey` on JeOS</title>
         <link>http://feedproxy.google.com/~r/mikewest/~3/tLtpBuWYFyo/running-python-spidermonkey-on-jeos</link>
         <description>&lt;p&gt;Paul Davis' &lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://github.com/davisp/python-spidermonkey/tree/master&quot;&gt;&lt;code&gt;python-spidermonkey&lt;/code&gt;&lt;/a&gt; project looks brilliant.&lt;/p&gt; &lt;p&gt;In a nutshell, he&amp;rsquo;s building a Python bridge to Mozilla&amp;rsquo;s &lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://www.mozilla.org/js/spidermonkey/&quot;&gt;SpiderMonkey&lt;/a&gt; &amp;ldquo;JavaScript on C&amp;rdquo; environment. I'm excited about that, because it means I might be able to put together a headless testing environment without trying to make everything work correctly inside Rhino. Hooray for options!&lt;/p&gt; &lt;p&gt;I ran into a snag or two while getting up and running on JeOS (my &lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://intranation.com/entries/2009/03/development-virtual-machines-os-x-using-vmware-and/&quot;&gt;dev environment of choice&lt;/a&gt;), so I'm documenting the process here.&lt;/p&gt; &lt;ol&gt;
&lt;li&gt;&lt;p&gt;Install python headers and &lt;code&gt;pkg-config&lt;/code&gt;. Forgetting to install
&lt;code&gt;pgk-config&lt;/code&gt; will give you some exciting errors in the compilation phase
later on that make it sound like NSPR failed to install correctly. If
you&amp;rsquo;re on JeOS, it&amp;rsquo;s more likely the case that you don&amp;rsquo;t have &lt;code&gt;pkg-config&lt;/code&gt;
at all:&lt;/p&gt; &lt;pre&gt;&lt;code&gt;sudo apt-get install python2.6-dev pkg-config
&lt;/code&gt;&lt;/pre&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Install netscape portable runtime:&lt;/p&gt; &lt;pre&gt;&lt;code&gt;sudo apt-get install libnspr4-dev
&lt;/code&gt;&lt;/pre&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Pull down python-spidermonkey&lt;/p&gt; &lt;pre&gt;&lt;code&gt;mkdir -p ~/src
cd ~/src
git clone git://github.com/davisp/python-spidermonkey.gitnsp
&lt;/code&gt;&lt;/pre&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Build &lt;code&gt;python-spidermonkey&lt;/code&gt;&lt;/p&gt; &lt;pre&gt;&lt;code&gt;cd ~/src/python-spidermonkey
python setup.py build
&lt;/code&gt;&lt;/pre&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Test &lt;code&gt;python-spidermonkey&lt;/code&gt;:&lt;/p&gt; &lt;p&gt;Actually, &lt;strong&gt;don&amp;rsquo;t&lt;/strong&gt; do this. &lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://davisp.lighthouseapp.com/projects/26898-python-spidermonkey/tickets/15-test_exceed_time-fails-on-jeos&quot;&gt;One of the tests fails on JeOS&lt;/a&gt;, and it
fails in a way that sucks up all your resources and leaves you in an
infinite loop. Yay!&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Install: Even though the max time test fails (spectacularly), the bridge
seems to work pretty well. Install the package anyway, just don&amp;rsquo;t rely on
being able to set a max execution time on your code. :)&lt;/p&gt; &lt;pre&gt;&lt;code&gt;sudo python setup.py install
&lt;/code&gt;&lt;/pre&gt;&lt;/li&gt;
&lt;/ol&gt; &lt;p&gt;Now, to see about getting &lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://jslint.com/&quot;&gt;JSLint&lt;/a&gt; running in this environment&amp;hellip; Fun!&lt;/p&gt; &lt;div class=&quot;feedflare&quot;&gt;
&lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://feeds.feedburner.com/~ff/mikewest?a=tLtpBuWYFyo:bdaxvUNDkpw:2mJPEYqXBVI&quot;&gt;&lt;img src=&quot;http://feeds.feedburner.com/~ff/mikewest?d=2mJPEYqXBVI&quot; border=&quot;0&quot;&gt;&lt;/a&gt; &lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://feeds.feedburner.com/~ff/mikewest?a=tLtpBuWYFyo:bdaxvUNDkpw:qZ7jBH1wJJ8&quot;&gt;&lt;img src=&quot;http://feeds.feedburner.com/~ff/mikewest?d=qZ7jBH1wJJ8&quot; border=&quot;0&quot;&gt;&lt;/a&gt; &lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://feeds.feedburner.com/~ff/mikewest?a=tLtpBuWYFyo:bdaxvUNDkpw:7Q72WNTAKBA&quot;&gt;&lt;img src=&quot;http://feeds.feedburner.com/~ff/mikewest?d=7Q72WNTAKBA&quot; border=&quot;0&quot;&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src=&quot;http://feeds.feedburner.com/~r/mikewest/~4/tLtpBuWYFyo&quot; height=&quot;1&quot; width=&quot;1&quot;/&gt;</description>
         <guid isPermaLink="false">http://mikewest.org/2009/05/running-python-spidermonkey-on-jeos</guid>
         <pubDate>Fri, 15 May 2009 17:00:00 -0700</pubDate>
      </item>
      <item>
         <title>The Value of Measurement</title>
         <link>http://feedproxy.google.com/~r/mikewest/~3/TyDwE-yoUas/the-value-of-measurement</link>
         <description>&lt;p&gt;While I agree fully with many of the conclusions Lukas Mathis draws in an &lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://ignorethecode.net/blog/2009/05/10/measuring-the-user-interface/&quot; title=&quot;Lukas Mathis: &amp;lsquo;Measuring the User Interface&amp;rsquo;&quot;&gt;excellent essay on the recent Google/Douglas Bowman split&lt;/a&gt;, a few bits deserve further study. Lukas hits the central problem squarely on the head in his &lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://ignorethecode.net/blog/2009/05/10/measuring-the-user-interface/#fn:google&quot;&gt;footnoted claim&lt;/a&gt; that measurement isn&amp;rsquo;t Google&amp;rsquo;s problem, rather the lack of a design team capable of &lt;em&gt;balancing&lt;/em&gt; those measurements against other concerns. I'd elaborate on this claim, and argue that the &lt;em&gt;kind&lt;/em&gt; of testing being discussed matters. In general, engineers understand and can relate well to automated A/B testing, and designers understand and can relate well to more personal usability testing. The two are, however, not the same, don&amp;rsquo;t provide the same data, and ought not be conflated.&lt;/p&gt; &lt;h2&gt;What do A/B tests test?&lt;/h2&gt; &lt;p&gt;&amp;ldquo;41 shades of blue&amp;rdquo; has become a catchphrase for those who see Google&amp;rsquo;s approach as flawed; this seemingly mindless insistence on A/B testing as the sole arbiter of a design&amp;rsquo;s &amp;ldquo;value&amp;rdquo; seems to me to be the point Bowman most objected to. I have a good amount of sympathy for that viewpoint.&lt;/p&gt; &lt;p&gt;A/B testing is, as Lukas rightly points out, hugely valuable to any team focused on improving an established system through a series of small, iterative changes. Serving a green button in place of a red button to 1% of your users, and discovering a statistically meaningful shift in usage patterns distinctly tells you something about your audience that no amount of surveying could. Ignoring these user&amp;rsquo;s &lt;em&gt;claims&lt;/em&gt; while carefully observing their &lt;em&gt;behavior&lt;/em&gt; can reveal interesting and useful bits of data about the way they interact with the interfaces you've built.&lt;/p&gt; &lt;p&gt;Especially with an audience the size of Google&amp;rsquo;s, you'd have to be crazy to write off the value of building small changes incrementally, and testing those piecemeal improvements against a subset of your audience. You&amp;rsquo;ll discover that one small tweak or another has an impact, and feed that back into your design process. Continually testing each iteration of tweaks against your audience will continually improve the quality of your pages and the overall user experience: It&amp;rsquo;s a virtuous circle of exactly the kind I'd like to encourage.&lt;/p&gt; &lt;p&gt;I absolutely stand behind the core of Lukas' essay: &amp;ldquo;Design is not held back by data, design is refined and perfected by data.&amp;rdquo;&lt;/p&gt; &lt;h2&gt;The Downside&lt;/h2&gt; &lt;p&gt;A/B testing is appealing because it&amp;rsquo;s obvious. It&amp;rsquo;s absolutely clear what needs to be done, the results are generally clear in the direction they lead (it&amp;rsquo;s either &amp;ldquo;A&amp;rdquo; or &amp;ldquo;B&amp;rdquo;), and if you have the tooling in place to make it easy (Google does), it&amp;rsquo;s easy to see how it can become a central part of the way you work.&lt;/p&gt; &lt;p&gt;That said, you'd be just as crazy to make &lt;em&gt;every&lt;/em&gt; decision dependent on this sort of testing. In order to isolate the effect of a change, as a true engineer-statistician ought demand, broad and sweeping suggestions should be broken down into testable components, and each served across a just-wide-enough swath of audience to return meaningful data while minimizing risk. An insistance on A/B measurement of each change, no matter how small, means that &lt;em&gt;everything&lt;/em&gt; you measure will be &amp;ldquo;trivial&amp;rdquo; in the way that the most glaring examples of &amp;ldquo;Googlism&amp;rdquo; have been: shades of colour, or widths of border. Only &lt;em&gt;trivial&lt;/em&gt; changes are &lt;em&gt;testable&lt;/em&gt; changes, everything else is fraught with layers of uncertainty: &amp;ldquo;Was it the new 3px border, or the new position of the button, or the completely new logo that drove traffic?&amp;rdquo; &amp;ldquo;Who knows, let&amp;rsquo;s do more tests!&amp;rdquo;&lt;/p&gt; &lt;p&gt;Moreover, it&amp;rsquo;s easy to see how a reliance on A/B testing might lead to a culture of extreme risk-aversion. When you have a ton of data at your fingertips that help guide your decisions, your worst enemy is the black hole that a new untested/untestable/unmeasured change represents. If a change isn&amp;rsquo;t testable/tested, it&amp;rsquo;s unknown. Unknown changes might be catastrophic. Catastrophic is bad. Therefore untested/untestable/unmeasured changes are, in the absence of &lt;em&gt;evidence&lt;/em&gt;, bad.&lt;/p&gt; &lt;p&gt;I suspect that Bowman isn&amp;rsquo;t at all exhorting his fellow designers to abstain completely from testing; I'd interpret his remarks as cutting against an &lt;em&gt;over-reliance&lt;/em&gt; on A/B testing. Within a primarily A/B framework, I'd consider it impossible to do &lt;em&gt;real&lt;/em&gt; design work that reevaluates a product&amp;rsquo;s decisions from first principles. Where can you begin? What interesting set of changes can you propose when each has to be buildable in a way that allows testing against the current status quo of the product as a baseline?&lt;/p&gt; &lt;p&gt;I believe that Bowman is right to worry about missing &amp;ldquo;truly great&amp;rdquo; designs by getting bogged down in continual, iterative improvement of a mediocre design. Getting wrapped up in asymptoticly approaching the &lt;em&gt;best&lt;/em&gt; shade of the &lt;em&gt;best&lt;/em&gt; button you can possibly create, and backing it all up with testing, might blind you to the fact that the action might really be better represented as a slider. Or a dropdown box. Or that it&amp;rsquo;s completely wrong and would be better reworked entirely.&lt;/p&gt; &lt;p&gt;Lukas quickly notes one answer in passing. I think it deserves more attention.&lt;/p&gt; &lt;h2&gt;Usability Testing and Prototypes&lt;/h2&gt; &lt;p&gt;In an &lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://machinist.salon.com/blog/2008/06/09/leander_kahney/index.html&quot;&gt;interview with Salon in 2008&lt;/a&gt;, Leander Kahney said:&lt;/p&gt; &lt;blockquote&gt;Steve Jobs doesn't wake up one morning and there's a vision of an iPhone floating in front of his face. He and his team discovered it through this exhaustive process of building prototype after prototype.&lt;/blockquote&gt; &lt;p&gt;Each of these prototypes functioned in one way or another, and each was put into someone&amp;rsquo;s hands to play with. This methodology of testing (especially for &lt;em&gt;new&lt;/em&gt; designs) is simply not measurable in the same way as determining whether a green link on a pre-existing page is clicked on more or fewer times than the same link in red. A/B testing &lt;em&gt;is not&lt;/em&gt; usability testing sweeping new prototypes; it has a different purpose, and gives different data points.&lt;/p&gt; &lt;p&gt;Prototyping new solutions to problems, and putting them in front of real people as quickly as possible, is probably the best way to make sweeping changes while maintaining some semblance of confidence that you&amp;rsquo;re moving in the right direction with regard to the audience you&amp;rsquo;re aiming for.&lt;/p&gt; &lt;p&gt;This sort of guerilla testing designs on friends and acquaintances with something like &lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://ignorethecode.net/blog/2008/08/04/silverback/&quot;&gt;Silverback&lt;/a&gt; absolutely ought to be part of the design process, early and often. Getting real feedback from people who &lt;em&gt;use&lt;/em&gt; the system you&amp;rsquo;re trying to improve is critical to designing and implementing an interface that makes the right tradeoffs in the right places.&lt;/p&gt; &lt;p&gt;In short, I'm highly sympathetic to the &lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;https://twitter.com/iA/statuses/1752478005&quot;&gt;Nielsenian notion&lt;/a&gt; that users &lt;em&gt;can&amp;rsquo;t&lt;/em&gt; and &lt;em&gt;won&amp;rsquo;t&lt;/em&gt; tell us what they want, that we need to examine their clicks in order to measure the impact of the changes we make. However, I think that notion needs to be tempered insofar as &lt;em&gt;never&lt;/em&gt; asking a user what she thinks is incredibly dangerous because it never allows you to break out of a certain comfort zone surrounding the product as it stands.&lt;/p&gt; &lt;p&gt;So. Test. Early, often, and persistently. Testing gives you immense amounts of data, and data is invaluable to your designs and implementations. But don&amp;rsquo;t limit your tests to those best expressed in a spreadsheet. Prototyping, and asking actual users actual questions, should be a part of your creative process.&lt;/p&gt; &lt;p&gt;Finally, to reiterate Lukas' point: you aren&amp;rsquo;t Google. Even if they&amp;rsquo;re dangerously-reliant on A/B testing, you almost certainly aren&amp;rsquo;t A/B testing &lt;em&gt;enough&lt;/em&gt;. I know I'm not&amp;hellip;&lt;/p&gt; &lt;div class=&quot;feedflare&quot;&gt;
&lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://feeds.feedburner.com/~ff/mikewest?a=TyDwE-yoUas:2L7NsrVQUhA:2mJPEYqXBVI&quot;&gt;&lt;img src=&quot;http://feeds.feedburner.com/~ff/mikewest?d=2mJPEYqXBVI&quot; border=&quot;0&quot;&gt;&lt;/a&gt; &lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://feeds.feedburner.com/~ff/mikewest?a=TyDwE-yoUas:2L7NsrVQUhA:qZ7jBH1wJJ8&quot;&gt;&lt;img src=&quot;http://feeds.feedburner.com/~ff/mikewest?d=qZ7jBH1wJJ8&quot; border=&quot;0&quot;&gt;&lt;/a&gt; &lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://feeds.feedburner.com/~ff/mikewest?a=TyDwE-yoUas:2L7NsrVQUhA:7Q72WNTAKBA&quot;&gt;&lt;img src=&quot;http://feeds.feedburner.com/~ff/mikewest?d=7Q72WNTAKBA&quot; border=&quot;0&quot;&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src=&quot;http://feeds.feedburner.com/~r/mikewest/~4/TyDwE-yoUas&quot; height=&quot;1&quot; width=&quot;1&quot;/&gt;</description>
         <guid isPermaLink="false">http://mikewest.org/2009/05/the-value-of-measurement</guid>
         <pubDate>Sat, 09 May 2009 17:00:00 -0700</pubDate>
      </item>
      <item>
         <title>DSL Woes</title>
         <link>http://feedproxy.google.com/~r/mikewest/~3/Lf0MkdJz6Es/dsl-woes</link>
         <description>&lt;p&gt;My DSL connection is really quite fast; I'm apparently only ~800m away from the nearest DSLAM, and so I should in theory be capable of maxing out the connection. This holds up pretty well in speed tests: I get great downstream, and passable upstream scores when connecting to pretty much anything in Europe.&lt;br/&gt;
&lt;/p&gt; &lt;p&gt;All told, I should be thrilled with my service, but I'm not, because it only seems to actually &lt;em&gt;work&lt;/em&gt; about 80% of the time. Every 10 minutes or so, my DSL modem gets confused about exactly what&amp;rsquo;s going on and drops the connection, picking it up again about a minute later, and continuing on it&amp;rsquo;s merry way with a new IP. This wreaks havok with any sort of persistant-connection driven tool, be it SSH or IRC or Adium&amp;hellip; drives me a bit nuts, actually. It&amp;rsquo;s gotten bad enough over the last few weeks that even Elisabeth notices the problem&amp;hellip; :)&lt;/p&gt; &lt;p&gt;I've been on the phone with &lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://www.hansenet.de/index.html&quot;&gt;Alice&lt;/a&gt; pretty regularly for a few weeks now, and it&amp;rsquo;s the same every time: I call in, explain the problem to the first-line tech, who checks the logs, asks me what kind of modem I have, and passes me on to the second-line tech, who checks the logs, asks me what kind of modem I have, and runs a line test. The line test is pretty much ok, but they pass it on to the third-line tech anyway. The third-line tech does whatever it is that they do, and calls up a few hours later to tell me that they don&amp;rsquo;t see any problem, but that they&amp;rsquo;ll replace something anyway. Last week it was the splitter. The time before that it was something in-between my apartment and the DSLAM. I'm curious to see what it&amp;rsquo;ll be this time. Maybe the modem?&lt;/p&gt; &lt;p&gt;I'm actually not as frustrated about this as I could be. The customer service has been more or less all that I could ask for (short of actually solving the problem, of course). The reps are friendly, seem relatively knowledgeable, and don&amp;rsquo;t treat me as though I'm the problem. I'd love for them to actually track down the bugs and get them worked out so that I don&amp;rsquo;t drop out of chat rooms every few minutes, but I'm willing to give them the benefit of the doubt so far. This is a marked contrast to our previous dealings with &lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://www.t-online.de/&quot;&gt;T-Online&lt;/a&gt; and Telekom in general, with whom I now simply refuse to do business based on the absurdity of the customer experience.&lt;/p&gt; &lt;p&gt;In any event, they&amp;rsquo;re working on my DSL again, and I'm hoping the days of &lt;code&gt;mikewest_&lt;/code&gt;, &lt;code&gt;mikewest__&lt;/code&gt;, and &lt;code&gt;mikewest___&lt;/code&gt; will soon be behind me.&lt;/p&gt; &lt;div class=&quot;feedflare&quot;&gt;
&lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://feeds.feedburner.com/~ff/mikewest?a=Lf0MkdJz6Es:cKygVHdE_7w:2mJPEYqXBVI&quot;&gt;&lt;img src=&quot;http://feeds.feedburner.com/~ff/mikewest?d=2mJPEYqXBVI&quot; border=&quot;0&quot;&gt;&lt;/a&gt; &lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://feeds.feedburner.com/~ff/mikewest?a=Lf0MkdJz6Es:cKygVHdE_7w:qZ7jBH1wJJ8&quot;&gt;&lt;img src=&quot;http://feeds.feedburner.com/~ff/mikewest?d=qZ7jBH1wJJ8&quot; border=&quot;0&quot;&gt;&lt;/a&gt; &lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://feeds.feedburner.com/~ff/mikewest?a=Lf0MkdJz6Es:cKygVHdE_7w:7Q72WNTAKBA&quot;&gt;&lt;img src=&quot;http://feeds.feedburner.com/~ff/mikewest?d=7Q72WNTAKBA&quot; border=&quot;0&quot;&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src=&quot;http://feeds.feedburner.com/~r/mikewest/~4/Lf0MkdJz6Es&quot; height=&quot;1&quot; width=&quot;1&quot;/&gt;</description>
         <guid isPermaLink="false">http://mikewest.org/2009/05/dsl-woes</guid>
         <pubDate>Sat, 09 May 2009 17:00:00 -0700</pubDate>
      </item>
      <item>
         <title>Ch-ch-ch-ch-changes</title>
         <link>http://foohack.com/2009/08/ch-ch-ch-ch-changes/</link>
         <description>Lot going on this summer. My roommate moved back to CT, meaning that I had to buy a car and get a new apartment. I moved from the YAP team to the YUI team. Also, I&amp;#8217;ve been spending more and more of my free time playing around with server-side Javascript, specifically Narwhal &lt;small&gt;&lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://foohack.com/2009/08/ch-ch-ch-ch-changes/&quot;&gt;...Read More&lt;/a&gt;&lt;/small&gt;</description>
         <guid isPermaLink="false">http://foohack.com/?p=138</guid>
         <pubDate>Thu, 27 Aug 2009 20:07:36 -0700</pubDate>
         <content:encoded><![CDATA[<p>Lot going on this summer. My roommate moved back to CT, meaning that I had to buy a car and get a new apartment. I moved from the YAP team to the YUI team. Also, I&#8217;ve been spending more and more of my free time playing around with server-side Javascript, specifically <a rel="nofollow" target="_blank" href="http://narwhaljs.org">Narwhal</a> and <a rel="nofollow" target="_blank" href="http://jackjs.org">Jack</a>. <a rel="nofollow" target="_blank" href="http://github.com/isaacs">My github account</a> has been pretty busy.</p>
<p>I won&#8217;t say that I&#8217;m retiring this blog, exactly, but the posting frequency may be dropping considerably. Instead of 1-2 posts every month or two, expect more like 1-2 posts a year, if that.</p>
<p>In the meantime, I&#8217;ve got all sorts of other stuff going on at <a rel="nofollow" target="_blank" href="http://blog.izs.me">my tumblr blog</a>, so you can follow me there.</p>]]></content:encoded>
         <category>foo</category>
      </item>
      <item>
         <title>Foo Hack 4.0</title>
         <link>http://foohack.com/2009/05/foohack-40/</link>
         <description>Partly because I haven&amp;#8217;t been writing much CSS these days, and partly because it&amp;#8217;s been just over a year since the last redesign, I felt like this site needed a face lift. Fonts I&amp;#8217;ve been getting more and more excited about the impending freedom of the @font-face CSS declaration. The prospect using any true-type or open-type &lt;small&gt;&lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://foohack.com/2009/05/foohack-40/&quot;&gt;...Read More&lt;/a&gt;&lt;/small&gt;</description>
         <guid isPermaLink="false">http://foohack.com/?p=124</guid>
         <pubDate>Tue, 05 May 2009 00:21:15 -0700</pubDate>
         <content:encoded><![CDATA[<p>Partly because I haven&#8217;t been writing much CSS these days, and partly because it&#8217;s been just over a year since the <a rel="nofollow" target="_blank" href="http://foohack.com/2008/02/foo-hack-redesign-30/">last redesign</a>, I felt like this site needed a face lift.</p>
<h2 id="fonts">Fonts</h2>
<p>I&#8217;ve been getting more and more excited about the impending freedom of the @font-face CSS declaration. The prospect using any true-type or open-type font in a web page without resorting to flash or images is incredible. If you&#8217;re viewing this site in Safari 4 or the latest beta releases of Firefox, Opera, and MSIE, you&#8217;ll have a much improved experience.</p>
<p><del>The body text is set in <a rel="nofollow" target="_blank" href="http://www.abstractfonts.com/search/bodoni svtytwo itc tt-book">Bodoni SvtyTwo OS</a>, chosen for its beautiful italics <small>(not an oblique, but a true italic)</small>, dramatic hinting, and straightforward lines. I chose the OS over the regular Bodoni SvtyTwo because of the more stylish &#8220;lower case&#8221; numerals: 1234567890.</del></p>
<p> Update : I decided to go with Hoefler Text instead of Bodoni. Bodoni looks nice, but without the stronger hinting, it was hard to read on some monitors, especially for folks who are crazy enough to browse the web on Windows. Hoefler Text has a lot of what I liked about Bodoni, and was a strong contender, but it&#8217;s not free-as-in-speech. However, it is <a rel="nofollow" target="_blank" href="http://twitter.com/izs/status/2752553503">free-as-in-MP3</a>, so I&#8217;ll use it until Hoefler &amp; Frere-Jones send me a C&amp;D . I also widened the column a bit to accommodate the wider typeface.</p>
<p>The headings are set in <a rel="nofollow" target="_blank" href="http://www.fontsquirrel.com/fonts/Qlassik-Medium">Qlassik Medium</a>, by Dimitri Castrigue. It has just enough fun to make it stand out, but not so much as to be ridiculous.</p>
<p>Code snippets are set in the famous <a rel="nofollow" target="_blank" href="http://ftp.gnome.org/pub/GNOME/sources/ttf-bitstream-vera/1.10/">Bitstream Vera Sans Mono</a>. I&#8217;d initially planned to set all things monotype in my favorite coding font, <a rel="nofollow" target="_blank" href="http://www.google.com/search?q=centschbook+mono">Century Schoolbook Mono</a>. Once you get used to coding with serifs, nothing else feels right. Unfortunately, it doesn&#8217;t include bold and italic versions. While the OS will &#8220;fake&#8221; bold and italics with fonts that it has installed, it won&#8217;t play ball when asked to manipulate dynamic fonts linked from a CSS file. I put CentSchBook Mono first, so if you have it <small>(which you should!)</small>, it&#8217;ll work. Otherwise, you&#8217;ll get Bitstream.</p>
<p>If you don&#8217;t have a browser that understands dynamic fonts, you can grab them from <a rel="nofollow" target="_blank" href="http://foohack.com/tpl/fonts/">http://foohack.com/tpl/fonts/</a>.</p>
<h2 id="layout">Layout</h2>
<p>I really wanted to stretch my CSS abilities a bit, and also apply some of the principles of typographic design that I&#8217;d been learning about lately. The single-column is about 66 characters wide in the target font, and feels about &#8220;right&#8221; for readability.</p>
<p>Despite my best intentions, a lot of feature creep had somehow taken over, prompting the last revamp. In this version, I put back some features that I&#8217;d removed, and removed some things I&#8217;d left in.</p>
<p>The vertical measure is set at 30px, with a font-size of 20px. While that&#8217;s a bit large, I&#8217;ve always favored erring on the side of &#8220;too big&#8221;, and the Bodoni just felt too cramped at 16/24.</p>
<p>I&#8217;ve also taken a lesson from the print world, and set all my bullets and other adornments off into the margins, such that the text is kept strictly flush left. The only element that I couldn&#8217;t figure out how to do this with is the <code>&lt;q&gt;</code> element when it starts a paragraph. In that case, it should have a text-indent somewhere around -0.5ex, but I couldn&#8217;t manage to do that without borking quotes that start somewhere in the middle of the paragraph.</p>
<p>Since all the major browsers support resizing fonts that are set in pixels, and &#8220;zooming&#8221; is now preferred over simple font resizing, I went ahead and set everything in pixels so that the math would be easier. There&#8217;s really no benefit to so-called &#8220;fluid&#8221; layouts that are set in ex or em measurements. Plus, browsers that support dynamic fonts seem to have a really hard time with ex/em measurements, since the layout is rendered before the font has downloaded. I do hope that gets fixed at some point, but doing layout in pixels was a welcome return to basics.</p>
<h2 id="supported_browsers">Supported Browsers</h2>
<p>The luxury of a personal site: I didn&#8217;t test even once in MSIE, and I don&#8217;t plan to.</p>
<p>Also, since a lot of the style is in the typography, anyone with a browser older than 6 months isn&#8217;t going to see my beautiful styles. But they&#8217;ll see their own default font settings, I suppose, and that&#8217;s probably fine. </p>
<p>What do you think?</p>]]></content:encoded>
      </item>
      <item>
         <title>1234567890</title>
         <link>http://foohack.com/2009/02/1234567890/</link>
         <description>Right now, the Unix Epoch Time is 1234567890. Is it excessively nerdy that I&amp;#8217;ve been looking forward to this for the past few years?</description>
         <guid isPermaLink="false">http://foohack.com/?p=120</guid>
         <pubDate>Fri, 13 Feb 2009 15:31:30 -0800</pubDate>
         <content:encoded><![CDATA[<p>Right now, the <a rel="nofollow" target="_blank" href="http://en.wikipedia.org/wiki/Unix_time">Unix Epoch Time</a> is 1234567890.</p>
<p>Is it excessively nerdy that I&#8217;ve been looking forward to this for the past few years?</p>]]></content:encoded>
         <category>Off Topic</category>
      </item>
      <item>
         <title>CSS vs Tables: You’re Doing It Wrong</title>
         <link>http://foohack.com/2009/02/css-vs-tables-youre-doing-it-wrong/</link>
         <description>Definitions first. Table A specified set of columns and rows with cells that automatically and fairly smartly expand to fit their contents; cells can span rows or columns; the table as a whole can be treated as one block, and cells can contain tables. A table is a metaphor for visually laying out 2-dimensional content. CSS cascading style sheets; &lt;small&gt;&lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://foohack.com/2009/02/css-vs-tables-youre-doing-it-wrong/&quot;&gt;...Read More&lt;/a&gt;&lt;/small&gt;</description>
         <guid isPermaLink="false">http://foohack.com/?p=108</guid>
         <pubDate>Mon, 02 Feb 2009 23:40:22 -0800</pubDate>
         <content:encoded><![CDATA[<p>Definitions first.
</p>
<dl>
<dt> Table </dt>
<dd>
<p> A specified set of columns and rows with cells that automatically and fairly smartly expand to fit their contents; cells can span rows or columns; the table as a whole can be treated as one block, and cells can contain tables. A table is a metaphor for visually laying out 2-dimensional content. </p>
</dd>
<dt> CSS </dt>
<dd>
<p> <em>cascading style sheets</em>; not floating divs, not any specific markup, but <em>just</em> the concept of the visual display of markup specified by a series of rules that are kept separate from the markup they operate on, generally in an external linked file or a style tag in the head of the document. </p>
</dd>
</dl>
<h3 id="talking_past_each_other"> Talking Past Each Other<br />
</h3>
<p> CSS is (for various reasons cited elsewhere ad nauseam), in most cases, the more optimal technological approach. That’s not to say that the existing state of the CSS language is perfect. In fact, even the most vocal CSS advocates regularly assert that there are deep problems with the existing spec and browser support.
</p>
<p> Tables are (for various reasons cited elsewhere ad nauseam), in most cases, a more optimal metaphor than any of its rivals. There’s nothing inherently wonderful about the tags themselves. In fact, even the most vocal table advocates regularly assert that the markup is ugly.
</p>
<p> Therein lies the crux of the problem. CSS is a great technological approach, and tables are a great metaphor. The question then usually becomes, <q>Should I mark up my content using <code>&lt;div&gt;</code> tags or <code>&lt;table&gt;</code> tags?</q>, which really means, <q>Is the separation of style from content more or less important than using the optimal layout metaphor?</q> The debate goes a little like this:
</p>
<dl>
<dt> tables </dt>
<dd>
<p> This layout metaphor is better, so you should use these tags. All you idealists are unrealistic! (Also, if you think markup matters, you believe in fairies. It so doesn&#8217;t!) </p>
</dd>
<dt> CSS </dt>
<dd>
<p> Metaphor shmetaphor! You don’t care about the sanctity of data or code quality. Think of the maintenance! (Also, if you can’t do it with divs, you’re stupid. It&#8217;s so easy!) </p>
</dd>
</dl>
<p> The Right Answer, it would seem, is to use the table metaphor with the CSS technology. In the ideal world, you’d always mark up your content using the tags that would communicate your meaning most clearly to your intended user agents. Then you’d tell user agents how to treat those tags visually. To describe this visual display, you should be able to use the table metaphor, or the float metaphor, or absolute and relative positioning, or anything else, <strong>but that should not be done by your markup</strong>.
</p>
<h3 id="getting_real"> Getting Real<br />
</h3>
<p> In the real world, it’s not so nice. The CSS specification has a set of display values designed to mimic the table tags, but they aren’t well supported, and anyway, it’s an imperfect imitation of a hack that was not really intended to be used the way we all ended up using it.
</p>
<p>In other words, CSS is not an ideal example of what CSS aims at, and the table/tr/td tags are not an ideal implementation of the table/grid metaphor. CSS tables, though they <em>are</em> clever and in some cases quite useful, take it from bad to worse.</p>
<p> The state of the CSS art is not at a point where you can realistically expect to make any significant stylistic changes to your pages without altering the markup. If you need to move the navigation bar from the right to the left, or re-skin the page with dropshadows instead of rounded corners, or convert your gradients from 2-tone to 3-tone, or make your boxes vertically centered instead of top-aligned, you’re probably going to have to change your markup, at least a little.
</p>
<p> In theory, it’s possible. I know a handful of my colleagues will vehemently disagree and point at countless approaches to enable virtually any kind of reskinning using only CSS changes. (I’ve used <a rel="nofollow" target="_blank" href="http://www.lesliesommer.com/wdw07/html/">Leslie Sommer’s CSS Mojo</a> technique to great success in the past; we used it for pretty much everything on <a rel="nofollow" target="_blank" href="http://buzz.yahoo.com">Yahoo! Buzz</a>.) But let me tell you, from years of experience building production sites with CSS, most of the time, in reality <strong>it just doesn’t work that way.</strong>
</p>
<p> And why should it? What kind of crazy lunatic writes <em>all their HTML by hand in text files</em>, anyhow? Clearly you have some kind of back-end engine spitting it out from templates, so you just change the template, and <em lang="fr">voilà!</em>, the markup is changed everywhere.
</p>
<h3 id="a_very_blue_bike_shed"> A Very Blue Bike Shed<br />
</h3>
<p> Working at Yahoo, I’ve met some webdevs with truly incredible CSS ability, who crank out live code under real deadlines to exacting standards. They use CSS, and not tables, and they Get Shit Done. There are a lot of them, more than I can list here, but <a rel="nofollow" target="_blank" href="http://nate.koechley.com/blog/">Nate Koechley</a>, <a rel="nofollow" target="_blank" href="http://github.com/msweeney">Matt Sweeney</a>, <a rel="nofollow" target="_blank" href="http://blog.hedgerwow.com/">Hedger Wang</a>, and <a rel="nofollow" target="_blank" href="http://www.lesliesommer.com/">Leslie Sommer</a> all deserve a special mention. I came to Yahoo knowing CSS pretty well, but I became an expert largely as a result of working in such a highly skilled community of developers.
</p>
<p> Also due to my time at Yahoo, I’ve seen some absolutely <em>crazy</em> debates about markup and coding standards on the devel-frontend mailing list. I mean, you think this little flare-up in the blogosphere is anything? You got no idea, buddy. Seriously. And these are coworkers who (for the most part) really like and respect one another.
</p>
<p> You wanna know a secret? <strong>It makes no difference.</strong>
</p>
<p> Language is as language does. If everyone uses the <code>&lt;table&gt;</code> tag for markup, guess what happens: <code>&lt;table&gt;</code> is now a semantically meaningless (or at least, semantically vague) tag, and any user agents that might care about navigating tabular data have to deal with that fact. It becomes just another <code>&lt;div&gt;</code>, for all intents and purposes, but a little less flexible, and with a default styling that makes it handy for layout.
</p>
<p> The passion for the rants <em>comes from</em> the fact that it is meaningless! Of <em>course</em> it’s a fertile ground for <a rel="nofollow" target="_blank" href="http://www.bikeshed.com/">bikeshedism</a>!
</p>
<h3 id="that8217s_right_it_doesn8217t_matter"> That’s right: It doesn’t matter.<br />
</h3>
<p> Use whatever tags work for you. I don’t care. You’ll still be a good person.
</p>
<p> I <em>can</em> tell you from experience that a deep knowledge of CSS is essential for serious front-end development. (Most so-called DHTML is actually just manipulating CSS with Javascript, and the Javascript is pretty light.) CSS can do some things that table tags can’t, so you ought to learn it. The reverse is also true, so you should know how to use tables, too.
</p>
<p> Write code that you can maintain, that is flexible enough to let you change it without sacrificing the stability of your product. Test it in the user agents that you expect to support. Stop debating the color of this bikeshed.
</p>
<p> If there’s ever a good reason to go back and change your tables to divs, or vice versa, you can do that. Hell, plan for that, because whether you use CSS for layout or not, you’re going to need to touch your markup sometimes. It is much much harder to build a product people want than it is to build a product that works in Browser X.</p>]]></content:encoded>
      </item>
      <item>
         <title>Will be moving to http://hedgerwow.blogspot.com/ in 3 days.</title>
         <link>http://feedproxy.google.com/~r/Hedgerwow/~3/4hCtrn2l1NI/</link>
         <description>Dear all.
I am done with DreamHost and will move to http://hedgerwow.blogspot.com/
Maybe I shall get a new domain or keep the existing one.
See you soon</description>
         <guid isPermaLink="false">http://blog.hedgerwow.com/?p=115</guid>
         <pubDate>Mon, 23 Nov 2009 00:07:41 -0800</pubDate>
         <content:encoded><![CDATA[<p>Dear all.</p>
<p>I am done with DreamHost and will move to<a rel="nofollow" target="_blank" href="http://hedgerwow.blogspot.com/"> http://hedgerwow.blogspot.com/</a><br />
Maybe I shall get a new domain or keep the existing one.</p>
<p>See you soon <img src='http://www.blog.hedgerwow.com/wp-includes/images/smilies/icon_smile.gif' alt=':-)' class='wp-smiley'/> </p>
<img src="http://feeds.feedburner.com/~r/Hedgerwow/~4/4hCtrn2l1NI" height="1" width="1"/>]]></content:encoded>
         <category>Uncategorized</category>
      </item>
      <item>
         <title>Preview image inline before uploading.</title>
         <link>http://feedproxy.google.com/~r/Hedgerwow/~3/MIRVV8USXQE/</link>
         <description>I hope HTML5 and Google Gear could do this thing better http://hedgerwow.appspot.com/image-upload-preview/demo.html</description>
         <guid isPermaLink="false">http://blog.hedgerwow.com/2009/06/03/preview-image-inline-before-uploading/</guid>
         <pubDate>Thu, 04 Jun 2009 00:12:55 -0700</pubDate>
         <content:encoded><![CDATA[<p>I hope HTML5 and Google Gear could do this thing better <img src='http://www.blog.hedgerwow.com/wp-includes/images/smilies/icon_smile.gif' alt=':-)' class='wp-smiley'/><br />
<a rel="nofollow" target="_blank" href="http://hedgerwow.appspot.com/image-upload-preview/demo.html ">http://hedgerwow.appspot.com/image-upload-preview/demo.html </a></p>
<img src="http://feeds.feedburner.com/~r/Hedgerwow/~4/MIRVV8USXQE" height="1" width="1"/>]]></content:encoded>
      </item>
      <item>
         <title>JOT: The JavaScript Object Template</title>
         <link>http://feedproxy.google.com/~r/Hedgerwow/~3/ic0K-T1fGPY/</link>
         <description>http://code.google.com/p/jot-project/wiki/SyntaxAndHowTos , still beta.
Hope you&amp;#8217;d like it.</description>
         <guid isPermaLink="false">http://blog.hedgerwow.com/2009/05/19/jot-the-javascript-object-template/</guid>
         <pubDate>Tue, 19 May 2009 14:05:56 -0700</pubDate>
         <content:encoded><![CDATA[<p><a rel="nofollow" target="_blank" href="http://code.google.com/p/jot-project/wiki/SyntaxAndHowTos">http://code.google.com/p/jot-project/wiki/SyntaxAndHowTos</a> <img src='http://www.blog.hedgerwow.com/wp-includes/images/smilies/icon_smile.gif' alt=':-)' class='wp-smiley'/> , still beta.</p>
<p>Hope you&#8217;d like it.</p>
<img src="http://feeds.feedburner.com/~r/Hedgerwow/~4/ic0K-T1fGPY" height="1" width="1"/>]]></content:encoded>
         <category>JavaScript</category>
      </item>
      <item>
         <title>Found a new JS pattern from MSDN.</title>
         <link>http://feedproxy.google.com/~r/Hedgerwow/~3/_cSfN2NXn8s/</link>
         <description>One day, I was trying to detect whether an element is an element that has no close tag.
So I did this:
var tagName = el.tagName.toLowerCase();
if( tagName == &amp;#8216;img&amp;#8217; &amp;#124;&amp;#124; tagName == &amp;#8216;br&amp;#8217; &amp;#124;&amp;#124; tagName == &amp;#8216;input&amp;#8217; &amp;#124;&amp;#124; tagName == &amp;#8216;embed &amp;#8216; ){
// This is just a example, not all single tags are tested. These tags are [...]</description>
         <guid isPermaLink="false">http://blog.hedgerwow.com/2009/04/30/found-a-new-js-pattern-from-msdn/</guid>
         <pubDate>Thu, 30 Apr 2009 13:36:26 -0700</pubDate>
         <content:encoded><![CDATA[<p>One day, I was trying to detect whether an element is an element that has no close tag.<br />
So I did this:</p>
<p>var tagName = el.tagName.toLowerCase();<br />
if( tagName == &#8216;img&#8217; || tagName == &#8216;br&#8217; || tagName == &#8216;input&#8217; || tagName == &#8216;embed &#8216; ){<br />
// This is just a example, not all single tags are tested. These tags are :<br />
// area,base,basefont,br,col,frame,hr,img,input,isindex,link,meta,param,embed.<br />
// Do something here.<br />
}</p>
<p>Well, this is not that efficient to write your program.<br />
So I switch to use a string map, which is rather simple and John Resig <a rel="nofollow" target="_blank" href="http://ejohn.org/files/htmlparser.js">uses </a>the same trick in his <a rel="nofollow" target="_blank" href="http://ejohn.org/blog/pure-javascript-html-parser/">HTML Parser.</a></p>
<p>var map = makeMap(&#8217;area,base,basefont,br,col,frame,hr,img,input,isindex,link,meta,param,embed&#8217;);<br />
if( map[tagName]){<br />
// Do something here.<br />
}</p>
<p>Of course we can use RegExp to test it, just like many others did.</p>
<p>var reg = /^(area|base|basefont|br|col|frame|hr|img|input|isindex|link|meta|param|embed)$/i;<br />
var tagName = &#8216;BR&#8217;;<br />
if( reg.test(tagName)){<br />
// Do something&#8230;<br />
}</p>
<p>and maybe you can find more tricks that solve the same problem with low cost, but below is the most interesting one that caught my attention.</p>
<p>if ( tagName != &#8220;BUTTON&#8221; | &#8220;B&#8221; | &#8220;A&#8221; ){<br />
// Do something&#8230;<br />
}</p>
<p>Wait, this seems really strange to me and seems not to perform as what I was expecting.<br />
However, since I found this code snippets from <a rel="nofollow" target="_blank" href="http://msdn.microsoft.com/en-us/library/ms537630(VS.85).aspx">MSDN</a>, there must be something magic which makes this working.</p>
<p><img title="js code snippets" alt="js code snippets" src="http://www.hedgerwow.com/360/dhtml/ms-crappy-js.png"/></p>
<p>Unfortunately, this is simply not working though I almost thought I found a new JS pattern from MSDN and was very excited about it for just about 10 seconds.</p>
<p>It&#8217;s fun to learn JS from microsoft.</p>
<blockquote >
<blockquote >
<img src="http://feeds.feedburner.com/~r/Hedgerwow/~4/_cSfN2NXn8s" height="1" width="1"/></blockquote></blockquote>]]></content:encoded>
         <category>JavaScript</category>
      </item>
      <item>
         <title>update:Cross Browser Base64 Encoded Images Embedded in HTML</title>
         <link>http://feedproxy.google.com/~r/Hedgerwow/~3/jwlz0mwKhWA/</link>
         <description>http://www.hedgerwow.com/360/dhtml/base64-image/demo.php</description>
         <guid isPermaLink="false">http://blog.hedgerwow.com/2009/04/16/updatecross-browser-base64-encoded-images-embedded-in-html/</guid>
         <pubDate>Thu, 16 Apr 2009 21:57:58 -0700</pubDate>
         <content:encoded><![CDATA[<p><a rel="nofollow" target="_blank" href="http://www.hedgerwow.com/360/dhtml/base64-image/demo.php ">http://www.hedgerwow.com/360/dhtml/base64-image/demo.php </a></p>
<img src="http://feeds.feedburner.com/~r/Hedgerwow/~4/jwlz0mwKhWA" height="1" width="1"/>]]></content:encoded>
         <category>image</category>
      </item>
      <item>
         <title>Notes from stylesheet-debug.js</title>
         <link>http://feedproxy.google.com/~r/Hedgerwow/~3/_Uq34Z_JHtQ/</link>
         <description>Below are the notes from the newly released YUI version 2.7.0 stylesheet.js
and the notes from its source probably explains why web development is too tricky to deal with. Adapted from tylesheet-debug.js.....
/*
Copyright (c) 2009, Yahoo! Inc. All rights reserved.
Code licensed under the BSD License:
http://developer.yahoo.net/yui/license.txt
version: 2.7.0
*/ * Style node must be added to the head element. [...]</description>
         <guid isPermaLink="false">http://blog.hedgerwow.com/2009/02/20/notes-from-stylesheet-debugjs/</guid>
         <pubDate>Fri, 20 Feb 2009 11:35:18 -0800</pubDate>
         <content:encoded><![CDATA[<div>Below are the notes from the newly released <a rel="nofollow" target="_blank" href="http://developer.yahoo.com/yui/stylesheet/">YUI version 2.7.0 stylesheet.js</a><br />
and the notes from its source probably explains why web development is too tricky to deal with.</div>
<pre style="font-family:courier new, monospace;">
<pre style="font-family:courier new, monospace;">
<pre style="font-family:courier new, monospace;"><font size="2">Adapted from tylesheet-debug.js.....</font></pre>
<pre style="font-family:courier new, monospace;"><font size="2">/*</font></pre>
<pre style="font-family:courier new, monospace;"><font size="2">Copyright (c) 2009, Yahoo! Inc. All rights reserved.
Code licensed under the BSD License:
http://developer.yahoo.net/yui/license.txt
version: 2.7.0</font></pre>
<p>*/</p>
<pre style="font-family:courier new, monospace;">
<pre style="font-family:courier new, monospace;"><font size="2">
* Style node must be added to the head element. Safari does not honor styles
applied to StyleSheet objects on style nodes in the body.
* StyleSheet object is created on the style node when the style node is added to the head element in Firefox 2 (and maybe 3?)
* The cssRules collection is replaced after insertRule/deleteRule calls in
Safari 3.1. Existing Rules are used in the new collection, so the collection
cannot be cached, but the rules can be. * Opera requires that the index be passed with insertRule.
* Same-domain restrictions prevent modifying StyleSheet objects attached to
link elements with remote href (or "about:blank" or "javascript:false") * Same-domain restrictions prevent reading StyleSheet cssRules/rules
collection of link elements with remote href (or "about:blank" or
"javascript:false")
* Same-domain restrictions result in Safari not populating node.sheet property for link elements with remote href (<a rel="nofollow" target="_blank" href="http://et.al/">et.al</a>)
* IE names StyleSheet related properties and methods differently (see code)
* IE converts tag names to upper case in the Rule's selectorText * IE converts empty string assignment to complex properties to value settings
for all child properties. E.g. style.background = '' sets non-'' values on
style.backgroundPosition, style.backgroundColor, etc. All else clear style.background and all child properties.
* IE assignment style.filter = '' will result in style.cssText == 'FILTER:'
* All browsers support Rule.style.cssText as a read/write property, leaving only opacity needing to be accounted for.
* Benchmarks of style.property = value vs style.cssText += 'property: value'
indicate cssText is slightly slower for single property assignment. For
multiple property assignment, cssText speed stays relatively the same where style.property speed decreases linearly by the number of properties set.
Exception being Opera 9.27, where style.property is always faster than
style.cssText.
* Opera 9.5b throws a syntax error when assigning cssText with a syntax error. * Opera 9.5 doesn't honor rule.style.cssText = ''. Previous style persists.
You have to remove the rule altogether.
* Stylesheet properties set with !important will trump inline style set on an element or in el.style.property.
* Creating a worker style collection like document.createElement('p').style;
will fail after a time in FF (~5secs of inactivity). Property assignments
will not alter the property or cssText. It may be the generated node is garbage collected and the style collection becomes inert (speculation).
* IE locks up when attempting to add a rule with a selector including at least
characters {[]}~`!@%^&#038;*()+=|? (unescaped) and leading _ or - such as addRule('-foo','{ color: red }') or addRule('._abc','{...}')
* IE's addRule doesn't support comma separated selectors such as
addRule('.foo, .bar','{..}') * IE throws an error on valid values with leading/trailing white space.
* When creating an entire sheet at once, only FF2/3 &#038; Opera allow creating a
style node, setting its innerHTML and appending to head. * When creating an entire sheet at once, Safari requires the style node to be
created with content in innerHTML of another element.
* When creating an entire sheet at once, IE requires the style node content to be set via node.styleSheet.cssText
* When creating an entire sheet at once in IE, styleSheet.cssText can't be
written until node.type = 'text/css'; is performed.
* When creating an entire sheet at once in IE, load-time fork on var styleNode = d.createElement('style'); _method = styleNode.styleSheet ?..
fails (falsey). During run-time, the test for .styleSheet works fine
* Setting complex properties in cssText will SOMETIMES allow child properties to be unset
set unset FF2 FF3 S3.1 IE6 IE7 Op9.27 Op9.5
---------- ----------------- --- --- ---- --- --- ------ -----
border -top NO NO YES YES YES YES YES -top-color NO NO YES YES YES
-color NO NO NO NO NO
background -color NO NO YES YES YES -position NO NO YES YES YES
-position-x NO NO NO NO NO
font line-height YES YES NO NO NO NO YES -style YES YES NO YES YES
-size YES YES NO YES YES
-size-adjust ??? ??? n/a n/a n/a ??? ??? padding -top NO NO YES YES YES
margin -top NO NO YES YES YES
list-style -type YES YES YES YES YES -position YES YES YES YES YES
overflow -x NO NO YES n/a YES ??? - unsetting font-size-adjust has the same effect as unsetting font-size * FireFox and WebKit populate rule.cssText as "SELECTOR { CSSTEXT }", but
Opera and IE do not.
* IE6 and IE7 silently ignore the { and } if passed into addRule('.foo','{
color:#000}',0). IE8 does not and creates an empty rule. * IE6-8 addRule('.foo','',n) throws an error. Must supply *some* cssText
*/</font></pre>
</pre>
</pre>
</pre>
<img src="http://feeds.feedburner.com/~r/Hedgerwow/~4/_Uq34Z_JHtQ" height="1" width="1"/>]]></content:encoded>
      </item>
      <item>
         <title>Be careful with getComputedStyle</title>
         <link>http://feedproxy.google.com/~r/Hedgerwow/~3/F3Eg0cgFD6E/</link>
         <description>Sometimes you really need to check whether an element is in the document already before calling some DOM methods.
See http://www.hedgerwow.com/360/bugs/dom-get-computed-style.php</description>
         <guid isPermaLink="false">http://blog.hedgerwow.com/2009/02/19/be-careful-with-getcomputedstyle/</guid>
         <pubDate>Thu, 19 Feb 2009 23:07:03 -0800</pubDate>
         <content:encoded><![CDATA[<p>Sometimes you really need to check whether an element is in the document already before calling some DOM methods.<br />
See <a rel="nofollow" target="_blank" href="http://www.hedgerwow.com/360/bugs/dom-get-computed-style.php">http://www.hedgerwow.com/360/bugs/dom-get-computed-style.php </a></p>
<img src="http://feeds.feedburner.com/~r/Hedgerwow/~4/F3Eg0cgFD6E" height="1" width="1"/>]]></content:encoded>
      </item>
      <item>
         <title>Imageless Fuzzy Shadows with CSS + HTML</title>
         <link>http://feedproxy.google.com/~r/Hedgerwow/~3/lhFN4YvoNa4/</link>
         <description>It&amp;#8217;s fun to play with CSS over 10 years.
Year 1999: filter:blur();
Year 2009: background:url(data:image/png;base64);
http://www.hedgerwow.com/360/dhtml/css_fuzzy_shadow/demo.php</description>
         <guid isPermaLink="false">http://blog.hedgerwow.com/2008/12/05/imageless-fuzzy-shadows-with-css-html/</guid>
         <pubDate>Fri, 05 Dec 2008 17:41:55 -0800</pubDate>
         <content:encoded><![CDATA[<p>It&#8217;s fun to play with CSS over 10 years.<br />
Year 1999: filter:blur();<br />
Year 2009: background:url(data:image/png;base64);<br />
<a rel="nofollow" target="_blank" href="http://www.hedgerwow.com/360/dhtml/css_fuzzy_shadow/demo.php">http://www.hedgerwow.com/360/dhtml/css_fuzzy_shadow/demo.php</a></p>
<p> <img src='http://www.blog.hedgerwow.com/wp-includes/images/smilies/icon_smile.gif' alt=':-)' class='wp-smiley'/> </p>
<img src="http://feeds.feedburner.com/~r/Hedgerwow/~4/lhFN4YvoNa4" height="1" width="1"/>]]></content:encoded>
      </item>
      <item>
         <title>What new Chief Technology Officer of the US need to do?</title>
         <link>http://feedproxy.google.com/~r/Hedgerwow/~3/n5otXVWPezY/</link>
         <description>Banning the use of IE6. I do believe it&amp;#8217;s just the right time to do the right change to make the internet faster, greener, cheaper, which helps to boost the poor economy.</description>
         <guid isPermaLink="false">http://blog.hedgerwow.com/2008/10/26/what-new-chief-technology-officer-of-the-us-need-to-do/</guid>
         <pubDate>Sun, 26 Oct 2008 14:16:29 -0700</pubDate>
         <content:encoded><![CDATA[<p><strong>Banning the use of IE6. </strong><br />
I do believe it&#8217;s just the right time to do the right change to make the internet faster, greener, cheaper, which helps to boost the poor economy.</p>
<img src="http://feeds.feedburner.com/~r/Hedgerwow/~4/n5otXVWPezY" height="1" width="1"/>]]></content:encoded>
         <category>Browsers</category>
      </item>
      <item>
         <title>Choosing a DOCTYPE that is just simple and strict</title>
         <link>http://feedproxy.google.com/~r/Hedgerwow/~3/0SU9CC2hx6A/</link>
         <description>I did not know this trick until I view the HTML source of a randomly search result from google http://www.hedgerwow.com/360/dhtml/short_doc_type.html</description>
         <guid isPermaLink="false">http://blog.hedgerwow.com/2008/10/16/choosing-a-doctype-that-is-just-simple-and-strict/</guid>
         <pubDate>Thu, 16 Oct 2008 15:53:25 -0700</pubDate>
         <content:encoded><![CDATA[<p>I did not know this trick until I view the HTML source of<br />
<a rel="nofollow" target="_blank" href="http://www.google.com/search?client=safari&#038;rls=en-us&#038;q=randomly+search+result&#038;ie=UTF-8&#038;oe=UTF-8"><br />
a randomly search</a> result from google</p>
<p></p>
<p><a rel="nofollow" target="_blank" href="http://www.hedgerwow.com/360/dhtml/short_doc_type.html"><br />
http://www.hedgerwow.com/360/dhtml/short_doc_type.html<br />
</a></p>
<img src="http://feeds.feedburner.com/~r/Hedgerwow/~4/0SU9CC2hx6A" height="1" width="1"/>]]></content:encoded>
      </item>
      <item>
         <title>Enliven your namespaces</title>
         <link>http://lucassmith.name/?p=122</link>
         <description>A namespace needn't be an inert object literal. It's just something to hang stuff off of, so technically it can be &lt;em&gt;anything that you can hang stuff off of&lt;/em&gt;. Among a host of other things, you can use functions instead of boring object literals to breathe some life into your namespaces.</description>
         <guid isPermaLink="false">http://lucassmith.name/?p=122</guid>
         <pubDate>Thu, 01 May 2008 09:59:32 -0700</pubDate>
         <content:encoded><![CDATA[<p>It&#8217;s a common good practice to use namespaces when writing your JavaScript. The reasons why have been stated <a rel="nofollow" target="_blank" href="http://www.dustindiaz.com/namespace-your-javascript/">time</a> <a rel="nofollow" target="_blank" href="http://www.ajaxprogrammer.com/?p=24">and</a> <a rel="nofollow" target="_blank" href="http://www.lixo.org/archives/2007/09/14/javascript-put-everything-in-a-namespace/">again</a> by <a rel="nofollow" target="_blank" href="http://yuiblog.com/blog/2006/06/01/global-domination/">much smarter</a> and <a rel="nofollow" target="_blank" href="http://snook.ca/archives/javascript/javascript_name/">more eloquent</a> people than myself, so suffice it to say, you should do it.</p>
<p>The typical method for namespacing has been to use object literals such as</p>
<pre class="code"><code>var myNS = { myFunc : function () { /* do stuff */ }
};</code></pre>
<p>However, A namespace needn&#8217;t be inert<sup><a rel="nofollow" href="#foot1">1</a></sup>. It&#8217;s just an object to hang stuff off of, so technically it can be <em>anything that you can hang stuff off of</em>. That is, anything that descends from Object, as well as other things like RegExp instances and, more interestingly, <em>functions</em>.</p>
<h3>Yay lambda</h3>
<p>In JavaScript, functions are first class objects. This allows code such as this:</p>
<pre class="code"><code>var foo = { bar : function (m) { alert(m); }
}; var barFunc = foo.bar;
var baz = { bar : foo.bar, goop : barFunc
}; // All of these will now do the same thing
foo.bar('Hello world');
barFunc('Hello world');
baz.bar('Hello world');
baz.goop('Hello world');
foo.bar.call(someRandomObject, 'Hello world');</code></pre>
<p>The only difference between them is the resolution of the <code>this</code> keyword.</p>
<h3>Breathe life into your namespace</h3>
<p>Let&#8217;s use a function as a namespace instead. Let&#8217;s say you have an object literal containing a suite of functions, but one function is called far more often than the others. We can use that function as the namespace, then alias the function name from within the namespace for consumers that like to type.</p>
<pre class="code"><code>// convenience function for merging objects
var set = function (to,from) { for (var k in from) { if (from.hasOwnProperty(k)) { to[k] = from[k]; } }
}; // create a namespace called <strong>node</strong> (in practice, choose something better)
var node = function (id) { return document.getElementById(id);
}; // Add functions to the function namespace just as you would to an object literal namespace
set(node, { byId : node, // alias to NS function for completeness /* &#8230; and then a few more functions that sit in the node namespace */ _templates : {}, create : function (name,conf,content) { var n = (this._templates[name] || (this._templates[name] = document.createElement(name)); if (n) { n = n.cloneNode(true); set(n,conf); // set things like className or innerHTML if (content) { n.innerHTML = n.innerHTML.replace(/{([&#92;w&#92;-&#92;s]+)}/g,function (x,placeholder) { return (placeholder in content) ? content[placeholder] : &#8221;; }); } } return n; }, remove : function (n) { if (n.parentNode) { n.parentNode.removeChild(n); } }, /* etc etc */
}); // Now you can use the namespace <em>node(x)</em> rather than type node.byId(x)
var n = node(&#8217;foo&#8217;);
var n1 = node.byId(&#8217;foo&#8217;); // synonyms // And of course, the rest of the functions work the same
var div = node.create(&#8217;div&#8217;,{className: &#8216;bar&#8217;, innerHTML: &#8216;&lt;p&gt;{message}&lt;/p&gt;&#8217;}, {message: &#8216;hello world&#8217;});</code></pre>
<h3>this()</h3>
<p>An interesting side effect of using a function as a namespace is that during the execution of functions under that namespace, <code>this</code> is resolved to the function ref. That means you can do something like</p>
<pre class="code"><code>var node = function (id) { return document.getElementById(id);
};
node.remove = function (id) { var n = <strong>this(id)</strong>; if (n &#038;&#038; n.parentNode) { n.parentNode.removeChild(n); }
};</code></pre>
<p>The use of <code>this</code> as a function ref in that case would cause a JavaScript error in the case where the <code>node.remove</code> function was not called from the <code>node</code> context such as in</p>
<pre class="code"><code>var rm = node.remove;
rm('boom'); // JavaScript error. 'this' evaluates to the global object (window) which isn't a function // or
node.remove.call(somethingOtherThanAFunction,'boom');</code></pre>
<p>But that&#8217;s a separate issue. The language has the capacity to be used in this way, and the value of leveraging this tactic needs to be evaluated and contrasted to the the potential breakages.</p>
<p>I&#8217;m personally a big fan of function namespaces, but it hadn&#8217;t occurred to me until just this morning that <code>this</code> also gained some super powers in the process. I haven&#8217;t yet thought of a case for its use (other than to trim code), but boy am I interested to hear suggestions!</p>
<ol>
<li id="foot1">Actually, even the object literal namespace isn&#8217;t inert. It brings with it all the methods and members that hang off of Object instances.</li>
</ol>]]></content:encoded>
         <category>Javascript</category>
      </item>
      <item>
         <title>label + checkbox concerns</title>
         <link>http://lucassmith.name/?p=121</link>
         <description>You have a label with a nested checkbox input element like so:
&amp;#60;label&amp;#62;&amp;#60;input type=&quot;checkbox&quot; value=&quot;foo&quot;&amp;#62;foo&amp;#60;/label&amp;#62;
When you click in the label area, all browsers except IE6 will fire the onclick event for the label followed by the onclick event for the input. IE6 will only fire the input&amp;#8217;s onclick if the label&amp;#8217;s for attribute is set [...]</description>
         <guid isPermaLink="false">http://lucassmith.name/?p=121</guid>
         <pubDate>Mon, 21 Apr 2008 15:27:04 -0700</pubDate>
         <content:encoded><![CDATA[<p>You have a label with a nested checkbox input element like so:</p>
<pre class="code"><code>&lt;label&gt;&lt;input type="checkbox" value="foo"&gt;foo&lt;/label&gt;</code></pre>
<p>When you click in the label area, all browsers <em>except</em> IE6 will fire the <code>onclick</code> event for the label followed by the <code>onclick</code> event for the input. IE6 will only fire the input&#8217;s <code>onclick</code> if the label&#8217;s <code>for</code> attribute is set and points to the <code>id</code> of the input.</p>
<pre class="code"><code>&lt;label for="x"&gt;&lt;input id="x" type="checkbox" value="foo"&gt;foo&lt;/label&gt;</code></pre>
<p>Also, both IE6 and IE7 will incorrectly render the following style:</p>
<pre class="code"><code>label { background: #def; padding: 2em 4em; }
input { margin-right: 2em; }</code></pre>
<p>Firefox<br />
<img alt="Firefox rendering. Solid blue label background" class="normal"/></p>
<p>IE<br />
<img alt="IE rendering. Blue label divided by margin" class="normal"/></p>
<p>And the icing: neither IE6 nor IE7 will fire the label&#8217;s <code>onclick</code> event for clicks occurring in the marginal space.<br />
<img alt="IE rendering with dead zone in margin area indicated" class="normal"/></p>]]></content:encoded>
         <category>Life</category>
      </item>
      <item>
         <title>Tyranny? I’m all for it!</title>
         <link>http://lucassmith.name/?p=120</link>
         <description>I sometimes wonder if the NPR newscasters feel frustrated because they are paid to relate some of the most inane drivel, but in the same tone as genuinely important information.
Pope Benedict XVI arrived in the US today, greeted by president Bush, and NPR got the pleasure of reporting that they shared many of the same [...]</description>
         <guid isPermaLink="false">http://lucassmith.name/?p=120</guid>
         <pubDate>Tue, 15 Apr 2008 20:35:45 -0700</pubDate>
         <content:encoded><![CDATA[<p>I sometimes wonder if the NPR newscasters feel frustrated because they are paid to relate some of the most inane drivel, but in the same tone as genuinely important information.</p>
<p>Pope Benedict XVI arrived in the US today, greeted by president Bush, and <a rel="nofollow" target="_blank" href="http://www.npr.org/"> NPR</a> got the pleasure of reporting that they shared many of the same values, such as opposition to tyranny and abortion.</p>
<p>That&#8217;s right, amongst their similar values, <em>opposing tyranny</em> was apparently distinct enough to be included in a summary list of two items. In case we might have thought that one or the other was (publicly) in favor of tyranny.</p>
<p>I wonder what else was on the list that didn&#8217;t make the cut&#8230;</p>
<p>They both like red?<br />
They both fear Jello?<br />
They both think stinky cheese is best left in France?<br />
They both think good stuff is better than bad stuff?</p>]]></content:encoded>
         <category>Life</category>
      </item>
      <item>
         <title>I &amp;lt;3 Firefox 3</title>
         <link>http://lucassmith.name/?p=118</link>
         <description>I just noticed Firefox 3 (on Mac) is rendering dotted borders rather interestingly.
It appears to start with a square in each corner with a half circle on the clockwise side, then circular dots spaced evenly between that semi-circle and the midway point of the next corner block. I played with it a bit and came up [...]</description>
         <guid isPermaLink="false">http://lucassmith.name/?p=118</guid>
         <pubDate>Fri, 11 Apr 2008 23:35:58 -0700</pubDate>
         <content:encoded><![CDATA[<p>I just noticed Firefox 3 (on Mac) is rendering dotted borders rather interestingly.</p>
<p>It appears to start with a square in each corner with a half circle on the clockwise side, then circular dots spaced evenly between that semi-circle and the midway point of the next corner block.<br />
<img class="normal" height="156" width="159" alt="Square-ish corners plus dots"/></p>
<p>I played with it a bit and came up with this:</p>
<pre class="code"><code>&lt;img style="border: 23px dotted #f99;" src="/images/blog/ff_hearts/firefox.png" height="49" width="49" alt="Firefox logo"&gt;</code></pre>
<p>Which renders like this on FF3b5 Mac:<br />
<img class="normal" height="115" width="115" alt="Dots become hearts at a certain ratio"/></p>
<p>Too bad I&#8217;m late for Valentines day.</p>]]></content:encoded>
      </item>
      <item>
         <title>I can has spambot</title>
         <link>http://lucassmith.name/?p=117</link>
         <description>I read on Wired the I Can Has Cheezburger folks started a new venture involving graphs/charts. Having such a chart lying around, I figured I&amp;#8217;d submit it. Apparently that was a big mistake.
I used to receive around 100 (properly filtered) spam messages per day, but the day after the submission, I&amp;#8217;m now receiving [...]</description>
         <guid isPermaLink="false">http://lucassmith.name/?p=117</guid>
         <pubDate>Sun, 30 Mar 2008 21:06:42 -0700</pubDate>
         <content:encoded><![CDATA[<p>I read <a rel="nofollow" target="_blank" href="http://blog.wired.com/underwire/2008/03/we-do-want-new.html">on Wired</a> the <a rel="nofollow" target="_blank" href="http://icanhascheezburger.com/">I Can Has Cheezburger</a> folks started a new venture involving graphs/charts. Having <a rel="nofollow" target="_blank" href="http://lucassmith.name/?p=53">such a chart</a> lying around, I figured I&#8217;d submit it. Apparently that was a big mistake.</p>
<p>I used to receive around 100 (properly filtered) spam messages per day, but the day after the submission, I&#8217;m now receiving nearly 2000, many of which have landed in my inbox.</p>
<h3>Chewbacca defense?</h3>
<p>Given normal circumstances, I probably would have considered this possibility and used my crap email, but it just so happened my keyboard had stopped working, behaving as though I&#8217;d changed the key mapping from qwerty to some approximation of <a rel="nofollow" target="_blank" href="http://en.wikipedia.org/wiki/Chewbacca_defense">wookie</a>.</p>
<p>In my stubborn insistence to do one simple thing before tearing the keyboard apart for deep cleaning (read: likely necessitating the purchase of a new one), I discovered that most of the qwerty right center row were represented by the top number keys and &#8216;a&#8217; was backspace. Between this and some random cutting and pasting into the email, I was able to eliminate the todo item and get busy extracting 3 years worth of lunch and dinner from my keyboard&#8217;s innards.</p>
<p>In my &#8230;haste? I overlooked the small detail of from address. I know 2000/day may not seem especially notable given the average email addy&#8217;s signal:noise ratio, but I had managed to do a pretty good job of keeping that account in the "light spam" department, even while displaying it here on ls.n (using some horrible, antiquated js obfuscation). It pains me to see the result of one slip.</p>
<p>Dear ICHC crew: bad form.</p>
<p>Spam sucks.</p>]]></content:encoded>
         <category>Life</category>
      </item>
      <item>
         <title>Yahoo! Messenger 10 beta</title>
         <link>http://gaarf.info/2009/08/25/yahoo-messenger-10-beta/</link>
         <description>Yahoo! Messenger 10 beta (windows download) was released yesterday. It is a major milestone for the instant messaging team, and for me in particular because it means the new insider page is now live! This is the project I have been working on for the past few months. It is essentially a mini version of [...]</description>
         <guid isPermaLink="false">http://gaarf.info/?p=394</guid>
         <pubDate>Tue, 25 Aug 2009 10:53:02 -0700</pubDate>
         <content:encoded><![CDATA[<p><a rel="nofollow" target="_blank" href="http://farm3.static.flickr.com/2613/3855973773_bf49be7bb0_o.png" title="Nifty New Insider"><img style="float:right;margin-left:1em;" src="http://farm3.static.flickr.com/2613/3855973773_c70975ccab_m.jpg" width="240" height="205" alt="Nifty New Insider"/></a></p>
<p>Yahoo! Messenger 10 <em>beta</em> (<a rel="nofollow" target="_blank" href="http://messenger.yahoo.com/winbeta">windows download</a>) was released yesterday. It is a major milestone for the instant messaging team, and for me in particular because it means the new <strong>insider page</strong> is now live! This is the project I have been working on for the past few months. It is essentially a mini version of the Yahoo! homepage built with <a rel="nofollow" target="_blank" href="http://developer.yahoo.com/yql/">YQL</a> <em>cloud technology</em>, complete with mail, news, weather, search assist, a high-revenue ad position, alternate stylesheets (skins!), a location picker, and there&#8217;s even an easter egg or two. Go find them if you can. <img src='http://gaarf.info/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley'/> </p>
<p>The page is intended to run &#8220;inside the IM client&#8221; but it works just fine in any modern browser window, too. Check it out <a rel="nofollow" target="_blank" href="http://insider.msg.yahoo.com/go/in5id3r/nifty?intl=us">here</a> (you will need a Yahoo! id).</p>]]></content:encoded>
         <category>default</category>
      </item>
      <item>
         <title>XML string to PHP array</title>
         <link>http://gaarf.info/2009/08/13/xml-string-to-php-array/</link>
         <description>One common need when working in PHP is a way to convert an XML document into a serializable array. If you ever tried to serialize() and then unserialize() a SimpleXML or DOMDocument object, you know what I&amp;#8217;m talking about.
Assume the following XML snippet:
&amp;#60;tv&amp;#62;
&amp;#160;&amp;#160;&amp;#60;show name=&amp;#34;Family Guy&amp;#34;&amp;#62;
&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#60;dog&amp;#62;Brian&amp;#60;/dog&amp;#62;
&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#60;kid&amp;#62;Chris&amp;#60;/kid&amp;#62;
&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#60;kid&amp;#62;Meg&amp;#60;/kid&amp;#62;
&amp;#160;&amp;#160;&amp;#60;/show&amp;#62;
&amp;#60;/tv&amp;#62;
There&amp;#8217;s a quick and dirty way to do convert such a [...]</description>
         <guid isPermaLink="false">http://gaarf.info/?p=358</guid>
         <pubDate>Thu, 13 Aug 2009 19:59:59 -0700</pubDate>
         <content:encoded><![CDATA[<p>One common need when working in PHP is a way to convert an XML document into a serializable array. If you ever tried to serialize() and then unserialize() a SimpleXML or DOMDocument object, you know what I&#8217;m talking about.</p>
<p>Assume the following XML snippet:</p>
<blockquote><p>&lt;tv&gt;<br />
&nbsp;&nbsp;&lt;show name="Family Guy"&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&lt;dog&gt;Brian&lt;/dog&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&lt;kid&gt;Chris&lt;/kid&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&lt;kid&gt;Meg&lt;/kid&gt;<br />
&nbsp;&nbsp;&lt;/show&gt;<br />
&lt;/tv&gt;</p></blockquote>
<p>There&#8217;s a quick and dirty way to do convert such a document to an array, using type casting and the JSON functions to ensure there are no exotic values that would cause problems when unserializing:</p>
<pre>&lt;?php $a = json_decode(json_encode((array) simplexml_load_string($s)),1);
?&gt;</pre>
<p>Here is the result for our sample XML, eg if we <code>print_r($a)</code>:</p>
<pre>Array
( [show] =&gt; Array ( [@attributes] =&gt; Array ( [name] =&gt; Family Guy ) [dog] =&gt; Brian [kid] =&gt; Array ( [0] =&gt; Chris [1] =&gt; Meg ) )
)</pre>
<p>Pretty nifty, eh? But maybe we want to embed some HTML tags or something crazy along those lines. then we need a CDATA node&#8230;</p>
<blockquote><p>&lt;tv&gt;<br />
&nbsp;&nbsp;&lt;show name="Family Guy"&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&lt;dog&gt;Brian&lt;/dog&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&lt;kid&gt;Chris&lt;/kid&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&lt;kid&gt;Meg&lt;/kid&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&lt;kid&gt;&lt;![CDATA[&lt;em&gt;Stewie&lt;/em&gt;]]&gt;&lt;/kid&gt;<br />
&nbsp;&nbsp;&lt;/show&gt;<br />
&lt;/tv&gt;</p></blockquote>
<p>The snippet of XML above would yield the following:</p>
<pre>Array
( [show] =&gt; Array ( [@attributes] =&gt; Array ( [name] =&gt; Family Guy ) [dog] =&gt; Brian [kid] =&gt; Array ( [0] =&gt; Chris [1] =&gt; Meg [2] =&gt; Array ( ) ) )
)</pre>
<p>That&#8217;s not very useful. We got in trouble because the CDATA node, a SimpleXMLElement, is being cast to an array instead of a string. To handle this case while still keeping the nice @attributes notation, we need a slightly more verbose conversion function. Here is my version, hereby released under a do-whatever-but-dont-sue-me license.</p>
<pre>&lt;?php
/** * convert xml string to php array - useful to get a serializable value * * @param string $xmlstr * @return array * @author Adrien aka Gaarf */
function xmlstr_to_array($xmlstr) { $doc = new DOMDocument(); $doc-&gt;loadXML($xmlstr); return domnode_to_array($doc-&gt;documentElement);
}
function domnode_to_array($node) { $output = array(); switch ($node-&gt;nodeType) { case XML_CDATA_SECTION_NODE: case XML_TEXT_NODE: $output = trim($node-&gt;textContent); break; case XML_ELEMENT_NODE: for ($i=0, $m=$node-&gt;childNodes-&gt;length; $i&lt;$m; $i++) { $child = $node-&gt;childNodes-&gt;item($i); $v = domnode_to_array($child); if(isset($child-&gt;tagName)) { $t = $child-&gt;tagName; if(!isset($output[$t])) { $output[$t] = array(); } $output[$t][] = $v; } elseif($v) { $output = (string) $v; } } if(is_array($output)) { if($node-&gt;attributes-&gt;length) { $a = array(); foreach($node-&gt;attributes as $attrName =&gt; $attrNode) { $a[$attrName] = (string) $attrNode-&gt;value; } $output[&#x27;@attributes&#x27;] = $a; } foreach ($output as $t =&gt; $v) { if(is_array($v) &amp;&amp; count($v)==1 &amp;&amp; $t!=&#x27;@attributes&#x27;) { $output[$t] = $v[0]; } } } break; } return $output;
}
?&gt;</pre>
<p>and the result, for our <em>Stewie</em> snippet:</p>
<pre>Array
( [show] =&gt; Array ( [@attributes] =&gt; Array ( [name] =&gt; Family Guy ) [dog] =&gt; Brian [kid] =&gt; Array ( [0] =&gt; Chris [1] =&gt; Meg [2] =&gt; &lt;em&gt;Stewie&lt;/em&gt; ) )
)</pre>
<p>Victory is mine! <img src='http://gaarf.info/wp-includes/images/smilies/icon_biggrin.gif' alt=':D' class='wp-smiley'/> </p>]]></content:encoded>
      </item>
      <item>
         <title>Upgraded to WordPress 2.8.x</title>
         <link>http://gaarf.info/2009/06/11/upgraded-to-wordpress-2-8/</link>
         <description>&lt;p&gt;&lt;strong&gt;Update&lt;/strong&gt;: now on &lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://wordpress.org/development/2009/08/2-8-4-security-release/&quot;&gt;2.8.4&lt;/a&gt; - &lt;em&gt;woooo!!!&lt;/em&gt;&lt;/p&gt;
&lt;img src=&quot;http://gaarf.info/wp-content/uploads/2008/08/wp-iphone.png&quot; alt=&quot;WordPress icon&quot; title=&quot;WordPress icon&quot; width=&quot;72&quot; height=&quot;72&quot; class=&quot;right noborder&quot; style=&quot;margin-left:4em;&quot;/&gt; &lt;p&gt;Growing tired of the &lt;strong&gt;constant WordPress updating&lt;/strong&gt;! Sigh&amp;#8230; &lt;/p&gt; &lt;p&gt;See the &lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://codex.wordpress.org/Version_2.8&quot;&gt;changelog&lt;/a&gt; for details on what is new in this release. Honestly I didn&amp;#8217;t even read it. Instead I chose to fall asleep while watching the &lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://wordpress.org/development/2009/06/wordpress-28/&quot;&gt;jazzy intro video&lt;/a&gt;.&lt;/p&gt; &lt;p&gt;[ &lt;em&gt;video embedded &lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://gaarf.info/2009/06/11/upgraded-to-wordpress-2-8/&quot;&gt;after the jump&lt;/a&gt;&lt;/em&gt; ]&lt;/p&gt;</description>
         <guid isPermaLink="false">http://gaarf.info/?p=343</guid>
         <pubDate>Thu, 11 Jun 2009 18:08:11 -0700</pubDate>
         <content:encoded><![CDATA[<p><strong>Update</strong>: now on <a rel="nofollow" target="_blank" href="http://wordpress.org/development/2009/10/wordpress-2-8-5-hardening-release/">2.8.5</a> &#8211; <em>woooo!!!</em></p>
<p><img src="http://gaarf.info/wp-content/uploads/2008/08/wp-iphone.png" alt="WordPress icon" title="WordPress icon" width="72" height="72" class="right noborder" style="margin-left:4em;"/></p>
<p>Growing tired of the <strong>constant WordPress updating</strong>! Sigh&#8230; </p>
<p>See the <a rel="nofollow" target="_blank" href="http://codex.wordpress.org/Version_2.8">changelog</a> for details on what is new in this release. Honestly I didn&#8217;t even read it. Instead I chose to fall asleep while watching the <a rel="nofollow" target="_blank" href="http://wordpress.org/development/2009/06/wordpress-28/">jazzy intro video</a>.</p>
<div style="padding:1em 4px;">
<iframe class="embeddedvideo" src="http://v.wordpress.com/Pu3T4X8l" type="application/x-shockwave-flash" width="500" height="280"></iframe>
</div>]]></content:encoded>
         <category>default</category>
      </item>
      <item>
         <title>Roadtrip Redux</title>
         <link>http://gaarf.info/2009/05/23/roadtrip-redux/</link>
         <description>Rejoice, Governator: I will be paying the state tax after all. Job prospects here in Texas are not all that great for Anne. In contrast, she has a number of opportunities in California. So, since it don&amp;#8217;t matter where I work from now that I&amp;#8217;m officially a telecommuting Yahoo!, we will be heading back [...]</description>
         <guid isPermaLink="false">http://gaarf.info/?p=336</guid>
         <pubDate>Sat, 23 May 2009 06:58:01 -0700</pubDate>
         <content:encoded><![CDATA[<p><a rel="nofollow" target="_blank" href="http://maps.yahoo.com/#mvt=m&#038;lat=37.020726&#038;lon=-109.077206&#038;zoom=6&#038;q1=Austin%2C%20TX&#038;w0=35.53222622770337%2C-97.470703125%3B40.713955826286046%2C-112.236328125&#038;q2=San%20Ramon%2C%20CA"><img src="http://gaarf.info/wp-content/uploads/2009/05/txca.png" alt="Northern route from Texas to California" title="Northern route from Texas to California" width="352" height="189" class="right"/></a>Rejoice, Governator: I will be paying the state tax after all. Job prospects here in Texas are not all that great for Anne. In contrast, she has a number of opportunities in California. So, since it don&#8217;t matter where I work from now that I&#8217;m officially a telecommuting Yahoo!, we will be heading back west next week, after my uncle and aunt return from their trip to Europe.</p>
<p>This time, we intend to take the northern route, via Oklahoma and Salt Lake City. As usual, stay tuned to <a rel="nofollow" target="_blank" href="http://twitter.com/gaarf">the Twitter</a> for updates!</p>]]></content:encoded>
         <category>road trip</category>
      </item>
      <item>
         <title>Moving back to Austin</title>
         <link>http://gaarf.info/2009/04/01/moving-back-to-austin/</link>
         <description>We have decided to move back to Austin, TX. Our appartement lease is up, all the stuff is in boxes, and I&amp;#8217;m getting ready for the transition from too much Sushi to too much Mexican food. I&amp;#8217;ll still be working (remotely) for Yahoo!.
The dot in the middle of the map is Roswell, NM &amp;#8211; where [...]</description>
         <guid isPermaLink="false">http://gaarf.info/?p=328</guid>
         <pubDate>Wed, 01 Apr 2009 15:06:36 -0700</pubDate>
         <content:encoded><![CDATA[<p><a rel="nofollow" target="_blank" href="http://maps.yahoo.com/#mvt=m&#038;lat=34.062304&#038;lon=-110.319766&#038;zoom=6&#038;q1=San%20Jose%2C%20CA&#038;w0=33.35806161277886%2C-104.5458984375&#038;q2=Austin%2C%20TX"><img src="http://gaarf.info/wp-content/uploads/2009/04/sjtx.png" alt="route from CA to TX" title="San Jose, CA to Austin, TX" width="343" height="151" class="right size-full wp-image-329"/></a></p>
<p>We have decided to move back to Austin, TX. Our appartement lease is up, all the stuff is in boxes, and I&#8217;m getting ready for the transition from too much Sushi to too much Mexican food. </p>
<p>I&#8217;ll still be working (remotely) for Yahoo!.</p>
<p>The dot in the middle of the map is Roswell, NM &#8211; where we will obviously stop for some dorky tourist trap. For realtime updates during the roadtrip <a rel="nofollow" target="_blank" href="http://twitter.com/gaarf">follow the Twitter</a>. </p>]]></content:encoded>
      </item>
      <item>
         <title>Re-tweaked h2o theme</title>
         <link>http://gaarf.info/2009/01/19/retweaked-h2o-theme/</link>
         <description>The theme used here, h2o, is becoming somewhat of a monstruosity. I really should write a completely new one. But for now, iterating already allows a little refresh, so behold a new hackishly re-tweaked theme!
Because of Twitter, I rarely post anything anymore&amp;#8230; so I went from two-posts on the homepage to just one. The header [...]</description>
         <guid isPermaLink="false">http://gaarf.info/?p=326</guid>
         <pubDate>Mon, 19 Jan 2009 16:24:24 -0800</pubDate>
         <content:encoded><![CDATA[<p>The theme used here, <a rel="nofollow" target="_blank" href="http://gaarf.info/h2o/">h2o</a>, is becoming somewhat of a <a rel="nofollow" target="_blank" href="http://gaarf.info/2006/12/02/updated-h20-theme-archive/">monstruosity</a>. I really should write a completely new one. But for now, iterating already allows a little refresh, so behold a new hackishly re-tweaked theme!</p>
<p><a rel="nofollow" target="_blank" href="http://gaarf.info/2007/11/22/giving-thanks-to-twitter/">Because of Twitter</a>, I rarely post anything anymore&#8230; so I went from two-posts on the homepage to just one. The header was also changed, hiding the description so that focus is now completely on the <em>latest tweet</em> block and it&#8217;s awesomely mind-blowing font-size animation. </p>
<p>Let me know what you think in the comments!</p>]]></content:encoded>
      </item>
      <item>
         <title>Upgraded to WordPress 2.7</title>
         <link>http://gaarf.info/2008/12/14/upgraded-to-wordpress-27/</link>
         <description>Wordpress&amp;#8216; new admin interface is very nice. The upgrade process was smooth as usual.
Growing tired of H20. I think I&amp;#8217;m going to tweak a theme again. This time I&amp;#8217;ll base it on YUI AutoGrid minimal and have support for widgets.
Then again, why mess with what works already ?</description>
         <guid isPermaLink="false">http://gaarf.info/2008/12/14/upgraded-to-wordpress-27/</guid>
         <pubDate>Sun, 14 Dec 2008 17:55:12 -0800</pubDate>
         <content:encoded><![CDATA[<p><a rel="nofollow" target="_blank" href="http://wordpress.org/development/2008/12/coltrane/">Wordpress</a>&#8216; new admin interface is very nice. </p>
<p>The upgrade process was smooth as usual.</p>
<p>Growing tired of H20. I think I&#8217;m going to tweak a theme again. This time I&#8217;ll base it on <a rel="nofollow" target="_blank" href="http://yuiblog.com/blog/2008/07/02/autogrid-wptheme/">YUI AutoGrid minimal</a> and have support for widgets.</p>
<p>Then again, why mess with what works already ?</p>]]></content:encoded>
      </item>
      <item>
         <title>Bloodbath Redux</title>
         <link>http://gaarf.info/2008/12/10/bloodbath-redux/</link>
         <description>I was not laid off today, but another set of co-workers were, including my immediate counterpart. Bits Blog (NYTimes.com) thinks that the Yahoo Layoffs Today May Not Be Last&amp;#8230; Yahoo began laying off 1,500 workers on Wednesday as part of a plan, announced in October, to slash expenses by $400 million a year. The cost cutting, [...]</description>
         <guid isPermaLink="false">http://gaarf.info/?p=317</guid>
         <pubDate>Wed, 10 Dec 2008 16:10:29 -0800</pubDate>
         <content:encoded><![CDATA[<p>I was not laid off today, but another set of co-workers were, including my immediate counterpart. <a rel="nofollow" target="_blank" href="http://bits.blogs.nytimes.com/2008/12/10/yahoo-layoffs-today-may-not-be-last/?pagemode=print">Bits Blog</a> (NYTimes.com) thinks that the <strong>Yahoo Layoffs Today May Not Be Last</strong>&#8230;</p>
<blockquote>
<p>Yahoo began laying off 1,500 workers on Wednesday as part of a plan, announced in October, to slash expenses by $400 million a year. The cost cutting, however, may have to go deeper in the coming year. </p>
<p>&#8220;There could be additional staff reductions next year,&#8221; said Brad Williams, a Yahoo spokesman. &#8220;It depends on the decisions we make about prioritization, and on things we can’t predict in the economy.&#8221; Mr. Williams added: &#8220;We are trying to instill a culture of cost-discipline in our business.&#8221; [He] also said that the job cuts today will affect most parts of the company, but that Yahoo executives are still evaluating which projects will be de-emphasized or cut altogether. &#8220;This is more of a cost reduction rather than business prioritization,&#8221; he said about the layoffs. &#8220;Business prioritization will continue going forward. We are looking at businesses we may put into maintenance mode.&#8221; </p>
<p>Yahoo&#8217;s chief executive, Jerry Yang, penned a <a rel="nofollow" target="_blank" href="http://ycorpblog.com/2008/12/10/tough-times/">farewell note</a> to laid-off employees on the company&#8217;s blog. If you want to know how managers are supposed to notify employees whose jobs are being cut, check out <a rel="nofollow" target="_blank" href="http://valleywag.com/5106184/yahoos-secret-layoff-doublespeak-revealed">Valleywag</a>.</p>
</blockquote>
<p>Sad day.</p>]]></content:encoded>
      </item>
      <item>
         <title>Yahoo! CEO Plans to Step Down</title>
         <link>http://gaarf.info/2008/11/18/yahoo-ceo-plans-to-step-down/</link>
         <description>Yahoo! said Monday evening that Jerry Yang, its chief executive, would step down from that role after the company finds a replacement.
Mr. Yang, a co-founder of Yahoo!, assumed control of the company a year and a half ago from Terry Semel, a Hollywood studio boss that he hand-picked for the job. His tenure has been [...]</description>
         <guid isPermaLink="false">http://gaarf.info/?p=310</guid>
         <pubDate>Tue, 18 Nov 2008 15:08:50 -0800</pubDate>
         <content:encoded><![CDATA[<p>Yahoo! said Monday evening that <em>Jerry Yang</em>, its chief executive, would step down from that role after the company finds a replacement.</p>
<blockquote><p>Mr. Yang, a co-founder of Yahoo!, assumed control of the company a year and a half ago from Terry Semel, a Hollywood studio boss that he hand-picked for the job. His tenure has been a tumultuous period during which Yahoo! <strong>rejected a $47.5 billion takeover offer</strong> from Microsoft and <strong>failed to cement</strong> an advertising partnership with Google.
</p></blockquote>
<ul>
<li><a rel="nofollow" target="_blank" href="http://bits.blogs.nytimes.com/2008/11/17/jerry-yang-yahoo-chief-plans-to-step-down/"> Jerry Yang, Yahoo Chief, Plans to Step Down &#8211; Bits Blog &#8211; NYTimes.com </a></li>
<li><a rel="nofollow" target="_blank" href="http://kara.allthingsd.com/20081118/yahoos-peter-chernin-principle-and-other-ceo-choices/">Yahoo&#8217;s CEO Choices | Kara Swisher | BoomTown | AllThingsD</a></li>
<li><a rel="nofollow" target="_blank" href="http://ycorpblog.com/2008/11/18/stepping-down/">Yodel Anecdotal &#8211; Stepping down (Jerry Yang)</a></li>
</ul>]]></content:encoded>
         <category>Yahoo!</category>
      </item>
      <item>
         <title>Obama &amp; Scientific Innovation</title>
         <link>http://gaarf.info/2008/11/05/obama-scientific-innovation/</link>
         <description>Yesterday, the American people chose Barack Obama as the country&amp;#8217;s 44th president, promising a sea change in US policy that could affect not just the US, but the whole world.
Take a look at what Obama has pledged over the lengthy presidential campaign, to see what his administration will mean for science and technology.
read more &amp;#124; [...]</description>
         <guid isPermaLink="false">http://gaarf.info/2008/11/05/obama-scientific-innovation/</guid>
         <pubDate>Wed, 05 Nov 2008 18:09:47 -0800</pubDate>
         <content:encoded><![CDATA[<p><img alt="Barack Obama" src="http://digg.com/general_sciences/Obama_promises_new_era_of_scientific_innovation/p.jpg" title="Obama promises new era of scientific innovation" class="right" width="160" height="110"/></p>
<p>Yesterday, the American people chose Barack Obama as the country&#8217;s 44th president, promising a sea change in US policy that could affect not just the US, but the whole world.</p>
<blockquote><p>Take a look at what Obama has pledged over the lengthy presidential campaign, to see what his administration will mean for science and technology.</p></blockquote>
<p><a rel="nofollow" target="_blank" href="http://www.newscientist.com/channel/opinion/dn15130-obama-promises-new-era-of-scientific-innovation.html?feedId=online-news_rss20">read more</a> | <a rel="nofollow" target="_blank" href="http://digg.com/general_sciences/Obama_promises_new_era_of_scientific_innovation">digg story</a></p>]]></content:encoded>
         <category>default</category>
      </item>
      <item>
         <title>A most Singular project</title>
         <link>http://salimismail.com/?p=120</link>
         <description>NASA Ames Exploration Center
Originally uploaded by Laughing Squid Over the last 2-3 months, a lot of people have been watching my tweets and listened to my various conversations wondering what exactly I&amp;#8217;m up to. I haven&amp;#8217;t been able to say much, but can now finally talk about it. Biting lips for this long has [...]</description>
         <guid isPermaLink="false">http://salimismail.com/?p=120</guid>
         <pubDate>Tue, 03 Feb 2009 03:36:07 -0800</pubDate>
         <content:encoded><![CDATA[<div style="float:right;margin-left:10px;margin-bottom:10px;">
<a rel="nofollow" target="_blank" href="http://www.flickr.com/photos/laughingsquid/465507180/" title="photo sharing"><img src="http://farm1.static.flickr.com/226/465507180_20f6f9f74c_m.jpg" alt="" style="border:solid 2px #000000;"/></a><br />
<span style="font-size:0.9em;margin-top:0px;"><br />
<a rel="nofollow" target="_blank" href="http://www.flickr.com/photos/laughingsquid/465507180/">NASA Ames Exploration Center</a><br />
Originally uploaded by <a rel="nofollow" target="_blank" href="http://www.flickr.com/people/laughingsquid/">Laughing Squid</a><br />
</span>
</div>
<p>Over the last 2-3 months, a lot of people have been watching my tweets and listened to my various conversations wondering what exactly I&#8217;m up to. I haven&#8217;t been able to say much, but can now finally talk about it. Biting lips for this long has been tough, but I can finally say I&#8217;m heading up <a rel="nofollow" target="_blank" href="http://singularityu.org/">Singularity University</a> &#8211; some great coverage from <a rel="nofollow" target="_blank" href="http://www.techcrunch.com/2009/02/02/world-renowned-scientists-team-with-google-and-nasa-to-launch-singularity-university/">TechCrunch </a>and <a rel="nofollow" target="_blank" href="http://news.cnet.com/8301-11386_3-10155303-76.html?tag=newsLeadStoriesArea.1">CNet</a> (among others).</p>
<p>I&#8217;ve been fascinated with innovation and growth for many years, and my experience at Yahoo <a rel="nofollow" target="_blank" href="http://www.techcrunch.com/2007/03/14/salim-ismail-to-head-yahoo-brickhouse/">building and running Brickhouse</a> was very foundational. Analyzing thousands of ideas, putting together great teams and working with some of the world&#8217;s best engineers to launch cutting edge products was a hell of a privilege. While at Yahoo, I established an important relationship between Brickhouse and NASA, which led to an invitation to the <a rel="nofollow" target="_blank" href="http://singularityu.org/about/founding-members/">founding meeting </a>of this initiative.</p>
<p>Once there, I was pretty well hooked. The vision that Ray Kurzweil and Peter Diamandis laid out was extremely compelling: Fundamentally, the world is facing some very large <a rel="nofollow" target="_blank" href="http://www.engineeringchallenges.org/">challenges </a>and the technologies identified by Ray can lead to scalable solutions to address these global issues. Add to that the interdisciplinary expertise brought by Peter&#8217;s experience and it was too much to pass up. They only had to ask once.</p>
<p>The full press release is <a rel="nofollow" target="_blank" href="http://singularityu.org/su-news-events/2009/02/singularity-university-to-study-accelerating-technologies-launches-at-nasa-ames/">here</a>.</p>
<p>Great innovation almost always happens when two disparate concepts are brought together. At SU, we&#8217;ll be bringing together dozens of experts across several distinct, accelerating technologies and letting them think about some of the grand challenges facing humanity. </p>
<p>A well-publicized example is 3D <a rel="nofollow" target="_blank" href="http://www.abcnews.go.com/Technology/story?id=1603783&#038;page=1">organ printing</a>. Scientists are combining 3D printing with stem stell research to &#8216;print&#8217; human organs. And that is one idea&#8230;<br />
<br clear="all"/></p>]]></content:encoded>
      </item>
      <item>
         <title>Analysis: Blackberry Curve vs. G1 Android</title>
         <link>http://salimismail.com/?p=114</link>
         <description>Blackberry Curve vs. G1 Android As part of a new project, our team was donated some G1 Android phones to play with. Already being a T-Mobile customer, it was a no-brainer to play with it for a couple of days and I got to put the phone through its paces. Here&amp;#8217;s what I discovered [...]</description>
         <guid isPermaLink="false">http://salimismail.com/?p=114</guid>
         <pubDate>Sun, 18 Jan 2009 18:49:15 -0800</pubDate>
         <content:encoded><![CDATA[<div style="float:right;margin-left:10px;margin-bottom:10px;">
<a rel="nofollow" target="_blank" href="http://www.flickr.com/photos/salimismail/3208567232/" title="photo sharing"><img src="http://farm4.static.flickr.com/3094/3208567232_53ae9eab2d_m.jpg" alt="" style="border:2px solid rgb(0, 0, 0);"/></a><br />
<br />
<span style="font-size:0.9em;margin-top:0px;"><br />
<a rel="nofollow" target="_blank" href="http://www.flickr.com/photos/salimismail/3208567232/">Blackberry Curve vs. G1 Android</a><br />
</span>
</div>
<p>As part of a new project, our team was donated some G1 Android phones to play with. Already being a T-Mobile customer, it was a no-brainer to play with it for a couple of days and I got to put the phone through its paces. Here&#8217;s what I discovered when comparing it to my Blackberry Curve (readers of this blog are no strangers to my endless attempts to optimize my mobile experience)&#8230;</p>
<p>SETUP<br />
=====<br />
Moving over to the G1 was very simple given I&#8217;ve been using a lot of Google services. I have Google Sync on my BB, so my contacts and calendar are already online and I use <a rel="nofollow" class="zem_slink" target="_blank" href="http://www.rememberthemilk.com" title="Remember The Milk">Remember The Milk</a> for task (mis)management, so that was also easy. I was up and running in less than 5 mins, including IMAP setup</p>
<p>THE PRO&#8217;S<br />
=========<br />
- the G1 is intuitive and easy to use with an excellent interface<br />
- the keyboard is surprisingly good and not having to hit &#8217;shift&#8217; for periods or numbers is huge &#8211; I could actually use this for medium-heavy typing efforts<br />
- I downloaded a few apps and they worked really well. The big draw for me was Skype (worked well) and tethering (which I didn&#8217;t finish configuring)<br />
- screen is awesome &#8211; very bright<br />
- browser is awesome &#8211; very thorough and easy to use<br />
- GPS! Fabulous (easy to update <a rel="nofollow" class="zem_slink" target="_blank" href="http://fireeagle.yahoo.net" title="Fire Eagle">FireEagle</a>)<br />
- youtube on the phone &#8211; excellent</p>
<p>CONS<br />
=====<br />
- profile &#8211; bigger and heavier than my Curve<br />
- battery life (SUCKS!) &#8211; big problem &#8211; lasts a half day with heavy use<br />
- sliding open and turning sideways everytime I have to type &#8211; slight hassle and requires two hands<br />
- calling someone requires way more clicks (and often, both hands)</p>
<p>SUMMARY<br />
========<br />
The Curve is totally optimized to be a great, great phone/email tool and other stuff (music, video) is secondary. The G1 is great for rich media but clunkier as a phone/email tool.</p>
<p>Overall, I&#8217;m sticking with the Blackberry for now as I make a lot of calls and emails and doing that really well with a whole day of battery life makes a big difference for me. But I will continue to play with the G1, and if I can get tethering working, then will carry it along on trips.<br />
<br clear="all"/></p>
<div style="margin-top:10px;height:15px;" class="zemanta-pixie"><a rel="nofollow" class="zemanta-pixie-a" target="_blank" href="http://reblog.zemanta.com/zemified/abaf0d2a-2da6-4e91-965b-61a391a68b61/" title="Zemified by Zemanta"><img style="border:medium none;float:right;" class="zemanta-pixie-img" src="http://img.zemanta.com/reblog_e.png?x-id=abaf0d2a-2da6-4e91-965b-61a391a68b61" alt="Reblog this post [with Zemanta]"/></a></div>]]></content:encoded>
      </item>
      <item>
         <title>Sonal Shah Appointed as Key Obama Adviser</title>
         <link>http://salimismail.com/?p=103</link>
         <description>Wow &amp;#8211; when it rains it pours. After eight years of Bush drought we finally get a big relief &amp;#8211; first Obama runs away with the election and now I just heard that he&amp;#8217;s appointed Sonal Shah to his inner circle.
I first met Sonal in 2003 at the awards gala where she was appointed India [...]</description>
         <guid isPermaLink="false">http://salimismail.com/?p=103</guid>
         <pubDate>Mon, 10 Nov 2008 02:33:13 -0800</pubDate>
         <content:encoded><![CDATA[<p><img src="http://salimismail.com/wp-content/uploads/2008/11/sonal-shah1.jpg" alt="" title="sonalshah" class="alignright size-full wp-image-112" width="201" height="222"/></p>
<p>Wow &#8211; when it rains it pours. After eight years of Bush drought we finally get a big relief &#8211; first Obama runs away with the election and now I just heard that he&#8217;s appointed Sonal Shah to his inner circle.</p>
<p>I first met Sonal in 2003 at the awards gala where she was appointed India Abroad&#8217;s Person of the Year for founding <a rel="nofollow" target="_blank" href="http://indicorps.org/">Indicorps</a>. Then she then came out to California to run a big chunk of Google.org and we were housemates for most of last year, during which we became very good friends. I haven&#8217;t seen her much recently as she&#8217;s been heavily involved helping with the campaign, so was taken quite unawares with this fabulous news. </p>
<p>I am, however, not at all surprised. Sonal is an extraordinary choice. She&#8217;s dedicated her life to social causes and philanthropy and is one of the wisest, brightest, most energetic people I know.</p>
<p>Certainly if I were President I&#8217;d have her in my inner circle <img src='http://salimismail.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley'/> )</p>
<p>Go Sonal!! The <a rel="nofollow" target="_blank" href="http://in.news.yahoo.com/48/20081106/1246/twl-indian-american-sonal-shah-appointed.html">full story is here</a>.</p>
<div style="margin-top:10px;height:15px;" class="zemanta-pixie"><a rel="nofollow" class="zemanta-pixie-a" target="_blank" href="http://reblog.zemanta.com/zemified/8018520b-d34e-4764-87f8-654021dd98b5/" title="Zemified by Zemanta"><img style="border:medium none;float:right;" class="zemanta-pixie-img" src="http://img.zemanta.com/reblog_e.png?x-id=8018520b-d34e-4764-87f8-654021dd98b5" alt="Reblog this post [with Zemanta]"/></a></div>]]></content:encoded>
      </item>
      <item>
         <title>Obama Wins – Thank The Lord…</title>
         <link>http://salimismail.com/?p=104</link>
         <description>It&amp;#8217;s Obama &amp;#8211; by a landslide&amp;#8230; Originally uploaded by Nicki&amp;#8217;s Knickers™ Readers of this blog (all three of them) will know that I don&amp;#8217;t often comment on politics. And though my twitter feed has leaned towards the democrats, I&amp;#8217;m more of a libertarian. Given the soaring heights of this occasion, though, I feel I [...]</description>
         <guid isPermaLink="false">http://salimismail.com/?p=104</guid>
         <pubDate>Mon, 10 Nov 2008 01:50:19 -0800</pubDate>
         <content:encoded><![CDATA[<div style="float:right;margin-left:10px;margin-bottom:10px;">
<a rel="nofollow" target="_blank" href="http://www.flickr.com/photos/nickiknickers/3018949228/" title="photo sharing"><img src="http://farm4.static.flickr.com/3063/3018949228_74b4cdb2e0_m.jpg" alt="" style="border:2px solid rgb(0, 0, 0);"/></a><br />
<br />
<span style="font-size:0.9em;margin-top:0px;"><br />
<a rel="nofollow" target="_blank" href="http://www.flickr.com/photos/nickiknickers/3018949228/">It&#8217;s Obama &#8211; by a landslide&#8230;</a><br />
<br />
Originally uploaded by <a rel="nofollow" target="_blank" href="http://www.flickr.com/people/nickiknickers/">Nicki&#8217;s Knickers™</a><br />
</span>
</div>
<p>Readers of this blog (all three of them) will know that I don&#8217;t often comment on politics. And though my twitter feed has leaned towards the democrats, I&#8217;m more of a libertarian. Given the soaring heights of this occasion, though, I feel I must break my non-blogging policy and put down a few thoughts. </p>
<p>First, the Republicans:<br />
- how can you call yourselves conservative after the insanity of the spending increases? What happened to fiscal prudence?<br />
- McCain, what in the name of all that is holy possessed you to put Palin on the ticket?<br />
- Dubya, there are better ways of handling unresolved paternal issues than lying, invading one country and bankrupting your own <br />
- Americans, how could you re-elect Bush in 2004? I mean, really&#8230; </p>
<p>And to the Democrats:<br />
- what have you been doing in the last six years??<br />
- please please don&#8217;t go too crazy with the spending<br />
- whatever you do, please fix the healthcare system</p>
<p>And to Obama:<br />
- many people I respect very highly got on planes or spent considerable time helping you out. That said it all for me. They include Sunil Paul, Robert Goldberg, Andrew Rasiej, Sonal Shah and who can forget Oprah leaning <a rel="nofollow" target="_blank" href="http://www.mercurynews.com/ci_10928838">on Sam Perry</a>&#8230; thrilling.</p>
<p>
There were times in the last 2-3 years that I despaired utterly for this country. Now I&#8217;m back up to &#8216;very concerned&#8217;.<br />
<br clear="all"/></p>
<div style="margin-top:10px;height:15px;" class="zemanta-pixie"><a rel="nofollow" class="zemanta-pixie-a" target="_blank" href="http://reblog.zemanta.com/zemified/5e49d472-2fa9-4a4b-b093-f1006af2e1da/" title="Zemified by Zemanta"><img style="border:medium none;float:right;" class="zemanta-pixie-img" src="http://img.zemanta.com/reblog_e.png?x-id=5e49d472-2fa9-4a4b-b093-f1006af2e1da" alt="Reblog this post [with Zemanta]"/></a></div>]]></content:encoded>
      </item>
      <item>
         <title>Maxroam Totally Rocks (a review)</title>
         <link>http://salimismail.com/?p=95</link>
         <description>On my second last trip to Ireland, Pat Phelan, one of my favorite bloggers, bounced into the speaker&amp;#8217;s dinner, handed me a SIM card and bounced right out again. Pat runs MaxRoam, a disruptive new telecoms play. On my recent trip, I put it through its paces. WHAT IT DOES
MaxRoam helps avoid [...]</description>
         <guid isPermaLink="false">http://salimismail.com/?p=95</guid>
         <pubDate>Wed, 18 Jun 2008 23:58:13 -0700</pubDate>
         <content:encoded><![CDATA[<p>On my second last trip to Ireland, <a rel="nofollow" target="_blank" href="http://patphelan.net/">Pat Phelan</a>, one of my favorite bloggers, bounced into the speaker&#8217;s dinner, handed me a SIM card and bounced right out again. Pat runs <a rel="nofollow" target="_blank" href="http://maxroam.com">MaxRoam</a>, a disruptive new telecoms play. On my recent trip, I put it through its paces. </p>
<p>WHAT IT DOES<br />
MaxRoam helps avoid international roaming charges. Simple. </p>
<p>HOW<br />
They put multiple numbers (all land lines) on the same SIM card. For instance, I have numbers for the U.S, Ireland, UK and Germany. If any of those numbers is called, my phone rings, wherever I am. I pay the local 25 cents (or whatever) charged by the local carrier. It costs 3 euros per month per number and you prepay the service. The SIM costs 25 euros. (Disclosure: because I&#8217;m an honorary Cork man, Pat gave me the SIM for free with a bit of credit to play with).</p>
<p>THE PROS<br />
- being landlines, it&#8217;s cheap for people to call you<br />
- you can get a new number right from the website and it works instantly (amazing)<br />
- you can forward (for free) any of your numbers to a local landline OR a local mobile and nobody pays. Outside North America, this is monstrously cost-saving as the caller usually pays (a fortune). Here, Maxroam swallows the costs.<br />
- 5 cent SMS worldwide (I didn&#8217;t test this)</p>
<p>THE CONS<br />
- you can&#8217;t put your current number onto it (but you can forward your number to it)<br />
- forwarding usually works, but occasionally it took 2-3 tries when I used it<br />
- lots of numbers to think about<br />
- you need a totally unlocked phone (I used an old Nokia)<br />
- not the greatest website in the world (but who cares, it works)</p>
<p>OVERALL<br />
After a bit of fiddling to get used to it, I&#8217;m hooked. I totally loved the service &#8211; can&#8217;t imagine traveling without it. Being able to forward a 212 number to a UK mobile and talking for hours for no charge internationally on a mobile was fabulous. I worked out I saved about $185 in my two week trip. The cost for my two weeks of rather frequent calling was about 14 euros. I&#8217;m hoping he adds a data service soon.</p>
<p>I think Pat is onto something really huge here. The addressable market for international roaming is monstrous, and creating an MVNO is a very interesting way of attacking it. I wish I could invest (Pat?, nudge wink?). More coverage on <a rel="nofollow" target="_blank" href="http://venturebeat.com/2007/09/17/maxroam-a-low-cost-alternative-for-mobile-international-calls/">VentureBeat </a>and <a rel="nofollow" target="_blank" href="http://www.techcrunch.com/2007/09/17/techcrunch-40-session-2-mobile-communications/">TechCrunch</a>.</p>
<p>Pat, by the way, is also behind <a rel="nofollow" target="_blank" href="http://twitterfone.com">Twitterfone</a>.</p>]]></content:encoded>
      </item>
      <item>
         <title>Europe trip log</title>
         <link>http://salimismail.com/?p=94</link>
         <description>Tom HC Bday card Wow, how bad a blogger am I (ok, I never really had the moniker anyway). But it&amp;#8217;s way long since I updated the ole papyrus. I&amp;#8217;ve been back from Europe for 2-3 weeks and it&amp;#8217;s been non-stop meetings since. Let&amp;#8217;s first start by recapping that trip.
First stop was London [...]</description>
         <guid isPermaLink="false">http://salimismail.com/?p=94</guid>
         <pubDate>Mon, 16 Jun 2008 12:42:44 -0700</pubDate>
         <content:encoded><![CDATA[<div style="float:right;margin-left:10px;margin-bottom:10px;">
<a rel="nofollow" target="_blank" href="http://www.flickr.com/photos/salimismail/2584203061/" title="photo sharing"><img src="http://farm4.static.flickr.com/3182/2584203061_7a51b932d1_m.jpg" alt="" style="border:solid 2px #000000;"/></a><br />
<span style="font-size:0.9em;margin-top:0px;"><br />
<a rel="nofollow" target="_blank" href="http://www.flickr.com/photos/salimismail/2584203061/">Tom HC Bday card</a><br />
</span>
</div>
<p>Wow, how bad a blogger am I (ok, I never really had the moniker anyway). But it&#8217;s way long since I updated the ole papyrus. I&#8217;ve been back from Europe for 2-3 weeks and it&#8217;s been non-stop meetings since. Let&#8217;s first start by recapping that trip.</p>
<p>First stop was London &#8211; a few meetings and some quality time with my god-daughters (little Irish identical twin girls). Next was Dublin for more meetings &#8211; I&#8217;m on the advisory board of <a rel="nofollow" target="_blank" href="http://putplace.com/">PutPlace</a>, so met with <a rel="nofollow" target="_blank" href="http://joedrumgoole.com/blog/">Joe Drumgoole</a> and then lunch with Joe and <a rel="nofollow" target="_blank" href="http://www.relevantm.com/">Niall Larkin</a>. Joe, after paying for lunch, also organized a very nice little <a rel="nofollow" target="_blank" href="http://www.mulley.net /2008/05/09/salim-ismail-in-dublin-on-may-12th/">meetup </a>and some interesting folks showed up, including <a rel="nofollow" target="_blank" href="http://www.pabcas.com/2008/5/19/the-easiest-way-to-work-less">Paul Campbell</a>, <a rel="nofollow" target="_blank" href="http://www.pix.ie">Marcus MacInnes</a>, <a rel="nofollow" target="_blank" href="http://www.contrast.ie">Eoghan McCabe</a> and <a rel="nofollow" target="_blank" href="http://www.dennisdeery.com/">Dennis Deery</a>. Oh yes, and I said hi to <a rel="nofollow" target="_blank" href="http://dehora.net/journal/">Bill de hÓra</a> for 60 secs as he whizzed by&#8230; good to see him again, albeit briefly.</p>
<p>Then it was off to Hamburg, where <a rel="nofollow">Sarik Weber</a> invited me to give a keynote address at the <a rel="nofollow" target="_blank" href="http://www.facebook.com/group.php?gid=11222753500">Facebook Developer Garage</a>. Nice reviews of my talk <a rel="nofollow" target="_blank" href="http://www.tell-it.net/webfact/archives/discover-the-latest-web-trends-and-news-selected-by-webfact">here</a> and <a rel="nofollow" target="_blank" href="http://www.lostfocus.de/archives/2008/05/19/zwei-tage-hamburg/">here </a>(if you read German).</p>
<p>Back in London, Tom Hughes-Croucher took me out to lunch and gave me this birthday card (like, a real one), which I haven&#8217;t seen for ages. Thanks Tom!</p>
<p>And finally, I met the BT/Osmosoft chaps&#8230; <a rel="nofollow" target="_blank" href="http://www.tiddlywiki.com/">Jeremy Ruston</a>, <a rel="nofollow" target="_blank" href="http://blog.whatfettle.com/">Paul Downey</a>, <a rel="nofollow" target="_blank" href="http://philwhitehouse.blogspot.com/">Phil Whitehouse</a>, <a rel="nofollow" target="_blank" href="http://www.hawksworx.com/journal/">Phil Hawksworth </a>and others. <a rel="nofollow" target="_blank" href="http://confabb.com">Confabb </a>is doing a very interesting collaboration with them that&#8217;ll beta at <a rel="nofollow" target="_blank" href="http://www.supernova2008.com/">SuperNova</a>.<br />
<br clear="all"/></p>]]></content:encoded>
         <category>Blogging</category>
      </item>
      <item>
         <title>Igniting Web 2.0 Expo</title>
         <link>http://salimismail.com/?p=92</link>
         <description>A proposal for an Ignite talk I submitted has been accepted for next weeks Web 2.0 Expo in San Francisco. It&amp;#8217;s going to be about the metaphysics of growth, something I&amp;#8217;ve been thinking, reading &amp;#038; writing about for about 15 years.
I touched on this topic very briefly at Brad Templeton&amp;#8217;s Nanotechnology Conference which we [...]</description>
         <guid isPermaLink="false">http://salimismail.com/?p=92</guid>
         <pubDate>Tue, 15 Apr 2008 12:35:56 -0700</pubDate>
         <content:encoded><![CDATA[<p><a rel="nofollow" target="_blank" href="http://sf.web2expo.com"><br />
<img src="http://conferences.oreillynet.com/banners/webexsf/promote/210x60.gif" width="210" height="60" border="0" alt="Web 2.0 Expo San Francisco 2008" title="Web 2.0 Expo San Francisco 2008"/><br />
</a></p>
<p>A proposal for an Ignite talk I submitted has been accepted for next weeks <a rel="nofollow" target="_blank" href="http://en.oreilly.com/webexsf2008/public/content/home">Web 2.0 Expo</a> in San Francisco. It&#8217;s going to be about the metaphysics of growth, something I&#8217;ve been thinking, reading &#038; writing about for about 15 years.</p>
<p>I <a rel="nofollow" target="_blank" href="http://salimismail.com/?p=72">touched </a>on this topic very briefly at Brad Templeton&#8217;s <a rel="nofollow" target="_blank" href="http://www.foresight.org/SrAssoc/2007/">Nanotechnology Conference</a> which we hosted at the Yahoo HQ.</p>
<p>This&#8217;ll be the first time I&#8217;ve ever talked about some of this stuff publicly, so the response should be interesting. The basic question is: &#8220;How does growth happen&#8221;? I&#8217;ll be talking about the basics of it and then applying the principles to the rapid growth environment of Silicon Valley.</p>
<p>Now all I have to do is write it&#8230; </p>]]></content:encoded>
      </item>
      <item>
         <title>Nevada Town Hall Politics (Live-blogging) – Part 3</title>
         <link>http://salimismail.com/?p=91</link>
         <description>Onto the Q&amp;#038;A&amp;#8230; this should be the fun stuff&amp;#8230;
Q: Why is x traffic study not being considered in your proposal
A: The study wasn&amp;#8217;t done in time
Q: You&amp;#8217;re claiming that after 400 new units the traffic will decrease?
A: [[can't hear answer]]
Crowd is getting raucous&amp;#8230; &amp;#8220;what are you doing about widening x [...]</description>
         <guid isPermaLink="false">http://salimismail.com/?p=91</guid>
         <pubDate>Wed, 19 Mar 2008 20:46:59 -0700</pubDate>
         <content:encoded><![CDATA[<p>Onto the Q&#038;A&#8230; this should be the fun stuff&#8230;</p>
<p>Q: Why is x traffic study not being considered in your proposal<br />
A: The study wasn&#8217;t done in time</p>
<p>Q: You&#8217;re claiming that after 400 new units the traffic will decrease?<br />
A: [[can't hear answer]]</p>
<p>Crowd is getting raucous&#8230; &#8220;what are you doing about widening x road&#8221;?</p>
<p>The questions are specific to individual situations&#8230; lots of side conversations starting at the back of the room&#8230; some people starting to leave. Some folks getting annoyed. This is fun stuff!</p>
<p>Tough questions now, and the developer folks are trying to keep the conversation civil. Lots of arguments about projected traffic numbers.</p>
<p>UPDATE:<br />
So I talked to some of the attendees afterwards and they said their complaint was that the developer plans to build way too many condos and time shares in Crystal Bay. The resulting project would increase the population of the town by about 4X, cause increased pressure on traffic, fire and pubic resources and be potentially detrimental to Lake Tahoe. Also their studies were curiously out of date. I have not talked to the developers yet, so this is a slightly one-sided viewpoint, but after hearing the presentation, I&#8217;d be extremely nervous if I lived there. Here&#8217;s a <a rel="nofollow" target="_blank" href="http://www.gopetition.com/online/17727.html">link to the petition</a> if anyone wants their voice heard&#8230;</p>]]></content:encoded>
         <category>Blogging</category>
      </item>
      <item>
         <title>Nevada Town Hall Politics (Live-blogging) – Part 2</title>
         <link>http://salimismail.com/?p=90</link>
         <description>Boulder Bay town hall mtg Originally uploaded by salimismail Second speaker is up&amp;#8230; mostly talking about road changes
&amp;#8220;&amp;#8230; we&amp;#8217;re putting in guard rails where necessary&amp;#8230;&amp;#8221;
&amp;#8220;&amp;#8230; heh heh.. well, that&amp;#8217;s it&amp;#8230;&amp;#8221;
&amp;#8220;&amp;#8230; if there&amp;#8217;s a wildfire, folks can use our parking lots&amp;#8230;&amp;#8221;
7.50pm &amp;#8211; Third speaker, who&amp;#8217;s a &amp;#8220;traffic engineer&amp;#8221; [...]</description>
         <guid isPermaLink="false">http://salimismail.com/?p=90</guid>
         <pubDate>Wed, 19 Mar 2008 20:07:16 -0700</pubDate>
         <content:encoded><![CDATA[<div style="float:right;margin-left:10px;margin-bottom:10px;"><a rel="nofollow" target="_blank" href="http://www.flickr.com/photos/salimismail/2346991098/" title="photo sharing"><img src="http://farm3.static.flickr.com/2110/2346991098_e86d0fff91_m.jpg" alt="" style="border:solid 2px #000000;"/> </a><br /><br /><span style="font-size:0.9em;margin-top:0px;"><br /><a rel="nofollow" target="_blank" href="http://www.flickr.com/photos/salimismail/2346991098/">Boulder Bay town hall mtg</a><br /> <br /> Originally uploaded by <a rel="nofollow" target="_blank" href="http://www.flickr.com/people/salimismail/">salimismail</a><br /> </span>
</div>
<p>Second speaker is up&#8230; mostly talking about road changes<br />
&#8220;&#8230; we&#8217;re putting in guard rails where necessary&#8230;&#8221;<br />
&#8220;&#8230; heh heh.. well, that&#8217;s it&#8230;&#8221;<br />
&#8220;&#8230; if there&#8217;s a wildfire, folks can use our parking lots&#8230;&#8221;</p>
<p>7.50pm &#8211; Third speaker, who&#8217;s a &#8220;traffic engineer&#8221; &#8211; now talking through the circulation plan. Claiming the traffic is actually declining in the area. Folks are mostly sporting pursed lips&#8230;. especially as he&#8217;s now estimating 0.5% traffic growth per year for the next 20 years.<br />
<br clear="all"/></p>]]></content:encoded>
         <category>Blogging</category>
      </item>
      <item>
         <title>Nevada Town Hall Politics (Live-blogging) – Part 1</title>
         <link>http://salimismail.com/?p=88</link>
         <description>Scene-setting: This is my first ever live-blogging effort. I&amp;#8217;m in a town hall-type meeting in Boulder Bay, Nevada (on the shore of Lake Tahoe).
The topic is a proposal to tear down the Tahoe Biltmore, a lovely old hotel, and replace it with a 400-unit condo complex. Local residents are not happy, and about [...]</description>
         <guid isPermaLink="false">http://salimismail.com/?p=88</guid>
         <pubDate>Wed, 19 Mar 2008 19:38:01 -0700</pubDate>
         <content:encoded><![CDATA[<p>Scene-setting: This is my first ever live-blogging effort. I&#8217;m in a town hall-type meeting in Boulder Bay, Nevada (on the shore of Lake Tahoe).</p>
<p>The topic is a proposal to tear down the Tahoe Biltmore, a lovely old hotel, and replace it with a 400-unit condo complex. Local residents are not happy, and about 250 of them are in this room listening with some suspicion. Apparently there was an earlier presentation in November which seems not to have gone down very well, especially around traffic congestion.</p>
<p>I&#8217;ve never witnessed small-town politics before, so this is new and fun stuff for me.</p>
<p>7.15pm &#8211; the developers are nervously starting a powerpoint presentation&#8230; sample quotes: &#8220;&#8230;we know a lot of you are worried about traffic&#8230;&#8221;<br />
&#8220;&#8230; this is a work in progress and will continue to evolve&#8230; &#8221;<br />
&#8220;&#8230; tourist-friendly wellness center&#8230; &#8221;<br />
&#8220;&#8230; these projects have a rumor mill&#8230; &#8221;</p>
<p>7.25pm &#8211; he&#8217;s now going through a set of slides diagramming what it&#8217;ll look like&#8230; lots of acronyms around project approvals</p>
<p>&#8220;&#8230; we are at the very early stages of this process&#8230; it&#8217;ll be a long time before anything gets decided&#8230; &#8221;</p>
<p>On to the next speaker&#8230; </p>]]></content:encoded>
         <category>Blogging</category>
      </item>
      <item>
         <title>Unix Permissions Calculator Released</title>
         <link>http://feedproxy.google.com/~r/ejeliot/blog-rss/~3/09ni3b86wpc/134</link>
         <description>&lt;p&gt;Over at &lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://projectfondue.com/&quot;&gt;Project Fondue&lt;/a&gt; we've just released a new tool - &lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://permissions-calculator.org/&quot;&gt;Permissions Calculator&lt;/a&gt;. If you always had trouble understanding how Unix file permissions worked then this is the tool for you.&lt;/p&gt;
&lt;p&gt;It allows you to specify the permissions you need by ticking checkboxes and it then generates the correct octal code for use with chmod. Alternatively supply it with an octal code and it'll provide a breakdown of what permissions that code corresponds to. The URL of the breakdown is bookmarkable making it easy to share with other people or to cross link from online documentation.&lt;/p&gt;
&lt;p&gt;Additionally the tool can generate the symbolic values needed to added permissions to an existing, base permissions set.&lt;/p&gt;</description>
         <guid isPermaLink="false">gg6L8PuW3BGXJwFvjtzu1g_6c2a70770d50c1dfb133c728173e271d</guid>
         <pubDate>Mon, 02 Mar 2009 06:55:12 -0800</pubDate>
      </item>
      <item>
         <title>Favicon Generator &amp; Editor Released</title>
         <link>http://feedproxy.google.com/~r/ejeliot/blog-rss/~3/k-FTYxP7k7k/133</link>
         <description>&lt;p&gt;I've been working on several projects with a couple of former colleagues (&lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://muffinresearch.co.uk/&quot;&gt;Stuart&lt;/a&gt; Colville &amp;amp; &lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://cyril.doussin.name/&quot;&gt;Cyril Doussin&lt;/a&gt;) and we've just released the first of these - a &lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://favicon-generator.org/&quot;&gt;favicon generator&lt;/a&gt;. The &lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://spritegen.website-performance.org/&quot;&gt;CSS Sprite Generator&lt;/a&gt; tool we released back in 2007 has also had a new lick of paint and we've set up &lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://projectfondue.com/&quot;&gt;Project Fondue&lt;/a&gt; to promote our work so check back often for new tools.&lt;/p&gt;
&lt;p&gt;Here's an extract from the about page text from the &lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://favicon-generator.org/&quot;&gt;Favicon Generator&lt;/a&gt; which explains exactly what it does.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;
This tool provides an easy way to convert any GIF, PNG or JPEG to ICO which is supported by all modern web browsers. It also enables you to create favicons from scratch via a handy online editor. Additionally the editor lets you manually tweak generated favicons to ensure the best possible result.
&lt;/p&gt;
&lt;/blockquote&gt;</description>
         <guid isPermaLink="false">gg6L8PuW3BGXJwFvjtzu1g_ef23ac1d81ded4f976a5e5fd15652118</guid>
         <pubDate>Mon, 09 Feb 2009 18:18:54 -0800</pubDate>
      </item>
      <item>
         <title>Inbound Link Analyser - a tool for analysing links to your site</title>
         <link>http://feedproxy.google.com/~r/ejeliot/blog-rss/~3/4zFiK2gy5II/132</link>
         <description>&lt;p&gt;&lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://ericmiraglia.com/&quot;&gt;Eric Migralia&lt;/a&gt;, of &lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://developer.yahoo.com/yui/&quot;&gt;Yahoo! YUI&lt;/a&gt; fame, has just released a tool, &lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://ericmiraglia.com/inlink/&quot;&gt;Inbound Link Analyser&lt;/a&gt;, for listing and analysing inbound links to any site. It's utilises YUI extensively and, I'm sure, provides a fantastic example of how to use a number of the core YUI components. I strongly recommend a browse around the source. Data for the tool is taken from &lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://developer.yahoo.com/search/siteexplorer/V1/inlinkData.html&quot;&gt;Yahoo!'s Site Explorer&lt;/a&gt; API and &lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://del.icio.us/&quot;&gt;del.icio.us&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;&lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://ericmiraglia.com/inlink/&quot; style=&quot;background:none;&quot;&gt;&lt;img src=&quot;http://ericmiraglia.com/assets/inlink.png&quot; alt=&quot;Page Inlink Analyzer UI.&quot; width=&quot;485&quot; style=&quot;border:none;&quot;&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;So far the tool has helped me unearth plenty of inbound links I hadn't discovered through the usual suspects (Google Analytics, Feedburner etc) so given how much I like trawling through this stuff I'm guessing I've got plenty of fun filled browsing ahead of me.&lt;/p&gt;
&lt;p&gt;The interface also lists other pages that have been indexed for the domain entered. Clicking on these or any of the inbound links opens separate tabs within the interface for you to analyse those resources further.&lt;/p&gt;
&lt;p&gt;&lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://ericmiraglia.com/blog/?p=72&quot;&gt;Eric's written a short introduction over on his blog&lt;/a&gt; (also newly released) so I'd suggest heading over there and checking that out first.&lt;/p&gt;
&lt;p&gt;&lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://ericmiraglia.com/inlink/?url=http://spritegen.website-performance.org/&quot;&gt;Here's a link to an analysis of my CSS Sprite Generation tool.&lt;/a&gt; It provides plenty of data to start exploring the tool with.&lt;/p&gt;</description>
         <guid isPermaLink="false">gg6L8PuW3BGXJwFvjtzu1g_5511ee9ae97668fc32012c24e9230884</guid>
         <pubDate>Tue, 14 Oct 2008 06:23:39 -0700</pubDate>
      </item>
      <item>
         <title>Vote for my SXSW 2009 panel proposal</title>
         <link>http://feedproxy.google.com/~r/ejeliot/blog-rss/~3/Bf6_mZXxHAE/131</link>
         <description>&lt;p&gt;&lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://muffinresearch.co.uk/&quot;&gt;Stuart&lt;/a&gt; Coville, &lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://www.stubbornella.org/&quot;&gt;Nicole Sullivan&lt;/a&gt;, &lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://www.phpied.com/&quot;&gt;Stoyan Stefanov&lt;/a&gt; and myself have put forward a panel proposal for SXSW 2009 - &lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://panelpicker.sxsw.com/ideas/view/1884/&quot;&gt;Practical Website Perfomance&lt;/a&gt;. We'll be covering a number of frontend techniques aimed at improving site performance, discussing how the way browsers work affects performance and generally discussing what we've learned about developing high traffic websites.&lt;/p&gt;
&lt;p&gt;If this interests you please take a moment and head over to the SXSW panel picker to &lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://panelpicker.sxsw.com/ideas/view/1884/&quot;&gt;vote for our panel&lt;/a&gt;.&lt;/p&gt;</description>
         <guid isPermaLink="false">gg6L8PuW3BGXJwFvjtzu1g_007843276db4aa50587461c2fb1549ab</guid>
         <pubDate>Thu, 14 Aug 2008 08:26:58 -0700</pubDate>
      </item>
      <item>
         <title>Source code for version 2 of CSS Sprite Generator</title>
         <link>http://feedproxy.google.com/~r/ejeliot/blog-rss/~3/IcTya3mU2Oo/130</link>
         <description>&lt;p&gt;&lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://muffinresearch.co.uk/&quot;&gt;Stuart&lt;/a&gt; and I have just released the source code for the latest version of our &lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://spritegen.website-performance.org/&quot;&gt;CSS Sprite Generator&lt;/a&gt;. As mentioned in my &lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://www.ejeliot.com/blog/129&quot;&gt;previous post&lt;/a&gt; the code has undergone a major refactoring and support for Image Magick has been added which greatly improves the quality of the images produced. Additionally there are options for tweaking the number of colours used in the output image, the image quality and for compressing images through &lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://optipng.sourceforge.net/&quot;&gt;OptiPNG&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;&lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;https://launchpad.net/css-sprite-generator&quot;&gt;Download a tar.gz of the source or check out the Bazaar branch.&lt;/a&gt;&lt;/p&gt;</description>
         <guid isPermaLink="false">gg6L8PuW3BGXJwFvjtzu1g_d26e5f6965eab764b629913417562b9d</guid>
         <pubDate>Sun, 13 Jul 2008 03:41:10 -0700</pubDate>
      </item>
      <item>
         <title>Version 2 of CSS Sprite Generator released</title>
         <link>http://feedproxy.google.com/~r/ejeliot/blog-rss/~3/saP5GqHoRt8/129</link>
         <description>&lt;p&gt;&lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://muffinresearch.co.uk/&quot;&gt;Stuart&lt;/a&gt; and I have just released a new version of our &lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://spritegen.website-performance.org/&quot;&gt;CSS Sprite Generator&lt;/a&gt;. We've given it quite a major overhaul and it now uses Image Magick to generate sprite images instead of GD. This produces much higher quality images and fixes all of the related bugs filed. Additionally we've added options to control the number of colours used in the sprite image for PNGs and GIFs and the image quality for JPEGs. Finally we've added an option to pass sprite images through &lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://optipng.sourceforge.net/&quot;&gt;OptiPNG&lt;/a&gt; to compress the output when using PNGs. This frequently results in at least a 50% decrease in file size and should save trips to Image Ready to post optimise your images.&lt;/p&gt;
&lt;p&gt;Behind the scenes we've completely restructured the code and heavily commented it to make it easier to understand. We'll be updating &lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;https://launchpad.net/&quot;&gt;Launchpad&lt;/a&gt; with this latest version of the code in the next few days. Stay tuned.&lt;/p&gt;
&lt;p&gt;The addition of these features has meant we're missing a number of translations. If you think you can help us fill in the gaps for your language please drop us a line or visit our &lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://spritegen.website-performance.org/section/your-language&quot;&gt;translation help page&lt;/a&gt; for more information.&lt;/p&gt;
&lt;p&gt;As you can imagine CSS Sprite Generator is very CPU intensive and therefore requires a fairly high quality hosting environment. To help support future development and hosting costs we're now selling a couple of small graphical button ads along side the text links we've sold on the site up until now. We've tried to ensure these have been added as unobtrusively as possible so hopefully they won't impact your experience whilst using the tool. &lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://spritegen.website-performance.org/section/advertising&quot;&gt;If you're interested in advertising we've got a page which gives all the details of the options available.&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;For the future we're mulling over a number of ideas for new features. One in particular is the addition of a REST based API (returning JSON and serialised PHP). We'd love to hear what you think about this and your thoughts on what else we should add to the tool going forward.&lt;/p&gt;</description>
         <guid isPermaLink="false">gg6L8PuW3BGXJwFvjtzu1g_7b397e101309f7d559c1ca6f102e5b3e</guid>
         <pubDate>Mon, 23 Jun 2008 05:42:06 -0700</pubDate>
      </item>
      <item>
         <title>Opera releases Dragonfly for Opera 9.5 beta 2</title>
         <link>http://feedproxy.google.com/~r/ejeliot/blog-rss/~3/7_AL7EipCos/128</link>
         <description>&lt;p&gt;Opera has released Dragonfly, their Firebug like developer console, as part of the latest release Opera 9.5 beta 2. It looks pretty promising - at a quick glance I think it compares favourably with the equivalent tool in Safari 3.&lt;/p&gt;
&lt;p&gt;The initial version includes a JavaScript Debugger, a DOM Inspector, CSS Inspector, error console and a command line and, although it doesn't currently offer editing capabilities, they'll follow shortly as well as the ability to inspect XHR/HTTP headers.&lt;/p&gt;
&lt;p&gt;I used Opera as my main browser for a couple of months at the start of the year but found myself reluctantly returning to Firefox as I was having to run it almost all the time anyway for access to the developer tools. The addition of editing capabilities to Dragonfly will likely see me return to Opera as I found it much snappier and memory usage over time much lower.&lt;/p&gt;
&lt;p&gt;More information and download details available from the &lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://www.opera.com/products/dragonfly/&quot;&gt;official Dragonfly web site.&lt;/a&gt; &lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://dev.opera.com/articles/view/introduction-to-opera-dragonfly/&quot;&gt;Chris Mills has also posted a detailed walk through explaining how to use the tool on the Opera Developer site.&lt;/a&gt;&lt;/p&gt;</description>
         <guid isPermaLink="false">gg6L8PuW3BGXJwFvjtzu1g_205c4a4f3ca9cc86295c1b186c49218d</guid>
         <pubDate>Tue, 06 May 2008 06:46:11 -0700</pubDate>
      </item>
      <item>
         <title>Mobile Browser Concurrency Test</title>
         <link>http://feedproxy.google.com/~r/ejeliot/blog-rss/~3/qNrfxd168PE/127</link>
         <description>&lt;p&gt;Cloud Four, specialists in mobile development, have set up a &lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://www.cloudfour.com/36/mobile-browser-concurrency-test/&quot;&gt;research project&lt;/a&gt; aimed at finding out more about the capabilities of mobile devices to determine the performance implications of building web sites for the wide variety of devices available. Inspired by desktop browser research, such as that carried out by &lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://developer.yahoo.com/performance/&quot;&gt;Yahoo!'s Exceptional Performance Team&lt;/a&gt;, they're particularly interested in finding out the following information:&lt;/p&gt;
&lt;ul&gt; &lt;li&gt;What is the number of concurrent http connections that the mobile browser supports both per domain and overall?&lt;/li&gt; &lt;li&gt;Does the mobile browser support gzip or other methods for reducing the size of pages?&lt;/li&gt; &lt;li&gt;Does the mobile browser support caching if you set the Expires header far into the future?&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;They plan to publish the information under a creative commons license to allow mobile web developers to benefit from their findings.&lt;/p&gt;
&lt;p&gt;&lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://www.cloudfour.com/36/mobile-browser-concurrency-test/&quot;&gt;You can help them by running their test suite from your mobile phone's web browser.&lt;/a&gt;&lt;/p&gt;</description>
         <guid isPermaLink="false">gg6L8PuW3BGXJwFvjtzu1g_40aca2a827f2c32e22b04aaff05cda19</guid>
         <pubDate>Mon, 28 Apr 2008 07:52:44 -0700</pubDate>
      </item>
      <item>
         <title>Problems building MySQLdb on Mac OS X 10.4 (Power PC)</title>
         <link>http://feedproxy.google.com/~r/ejeliot/blog-rss/~3/xNs4reMEFEY/126</link>
         <description>&lt;p&gt;Over the last couple of days I've been trying to build and install &lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://sourceforge.net/projects/mysql-python&quot;&gt;MySQLdb&lt;/a&gt; on my PowerPC based Mac Mini with very little success. I got the following message followed by a ton of type errors:&lt;/p&gt;
&lt;pre&gt;
Compiling with an SDK that doesn't seem to exist: /Developer/SDKs/MacOSX10.4u.sdk
Please check your Xcode installation
&lt;/pre&gt;
&lt;p&gt;I tried reinstalling Xcode Tools to see if it would solve the problem but with no success. Anyway after searching around it turns out that the installer doesn't add a required SDK package which you can find in Xcode Tools-&amp;gt;Packages on the install disk. It's called MacOSX10.4.Universal.pkg.&lt;/p&gt;
&lt;p&gt;I (and others) have not had similar problems on Intel based Macs running Tiger or Leopard so I'm guessing it's specific to the PPC install.&lt;/p&gt;
&lt;p&gt;With that out of the way - on with &lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://www.djangoproject.com/&quot;&gt;Django&lt;/a&gt;.&lt;/p&gt;</description>
         <guid isPermaLink="false">gg6L8PuW3BGXJwFvjtzu1g_1b907e4b6b3c56300a88a89ca80ee3b5</guid>
         <pubDate>Wed, 16 Apr 2008 20:00:07 -0700</pubDate>
      </item>
      <item>
         <title>Automatic versioning of CSS, JavaScript and Images</title>
         <link>http://feedproxy.google.com/~r/ejeliot/blog-rss/~3/A6iZbBRByGI/125</link>
         <description>&lt;p&gt;&lt;em&gt;See comments for important information about HTTP caching issues with URLs containing query string parameters.&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;When including CSS and JavaScript resources in your pages you should version file paths and update these version numbers every time the files change. This is necessary as a visitor's browsers may, depending on settings, continue to cache files even after a change. This can result in a mismatch between your HTML and these external resources which may cause rendering or functionality problems. One will likely encounter similar caching issues with images.&lt;/p&gt; &lt;p&gt;So if we work on the basis that we should version these resources and that changing version numbers forces the browser to reload those resources then we can actually gain large performance improvements by explicitly instructing the browser to cache them for an extended period of time (say 10 years) thereby limiting the number of times the browser goes back to check for fresh copies.&lt;/p&gt; &lt;p&gt;This can be achieved fairly easily within the virtual host settings of your Apache conf file. Simply add the following directives within the relevant virtual hosts section substituting /assets/ with the file path corresponding to the location where your CSS, JavaScript and images are stored.&lt;/p&gt; &lt;ol class=&quot;code&quot;&gt; &lt;li&gt;&lt;code&gt;&amp;lt;Location /assets/&amp;gt;&lt;/code&gt;&lt;/li&gt; &lt;li class=&quot;indent1&quot;&gt;&lt;code&gt;ExpiresActive On&lt;/code&gt;&lt;/li&gt; &lt;li class=&quot;indent1&quot;&gt;&lt;code&gt;ExpiresDefault &quot;access plus 10 years&quot;&lt;/code&gt;&lt;/li&gt; &lt;li&gt;&lt;code&gt;&amp;lt;/Location&amp;gt;&lt;/code&gt;&lt;/li&gt;
&lt;/ol&gt; &lt;p&gt;If you have the mod_deflate module installed then you can gain an additional performance benefit by gzipping CSS and JavaScript resources to reduce the amount transmitted down the wire.&lt;/p&gt; &lt;ol class=&quot;code&quot;&gt; &lt;li&gt;&lt;code&gt;&amp;lt;Location /assets/&amp;gt;&lt;/code&gt;&lt;/li&gt; &lt;li class=&quot;indent1&quot;&gt;&lt;code&gt;ExpiresActive On&lt;/code&gt;&lt;/li&gt; &lt;li class=&quot;indent1&quot;&gt;&lt;code&gt;ExpiresDefault &quot;access plus 10 years&quot;&lt;/code&gt;&lt;/li&gt; &lt;li class=&quot;indent1&quot;&gt;&lt;code&gt;SetOutputFilter DEFLATE&lt;/code&gt;&lt;/li&gt; &lt;li&gt;&lt;code&gt;&amp;lt;/Location&amp;gt;&lt;/code&gt;&lt;/li&gt;
&lt;/ol&gt; &lt;p&gt;These directives can also be added to an appropriately placed .htaccess file but as &lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://muffinresearch.co.uk/archives/2008/04/07/avoiding-the-use-of-htaccess-for-performance/&quot;&gt;Stuart&lt;/a&gt; explains there are performance implications with this method so it should only be chosen if you don't have access to your Apache conf files (perhaps because you're using shared hosting).&lt;/p&gt; &lt;p&gt;Applying both these settings covers off a couple of recommendations made by &lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://developer.yahoo.com/yslow/&quot;&gt;Yahoo!'s YSlow performance testing tool&lt;/a&gt; so not only will you end up with a faster site but you'll also improve your YSlow rating by a grade or two.&lt;/p&gt; &lt;p&gt;Of course manually versioning files is a pain, it's repetitive and as &lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://muffinresearch.co.uk/&quot;&gt;Stuart&lt;/a&gt; is always reminding me manually repetitive tasks should be eliminated wherever possible. In the past I wrote a &lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://www.ejeliot.com/blog/72&quot;&gt;script which automatically merges CSS or JavaScript files&lt;/a&gt; and versions the combined output. Here's some simpler code which versions individual files based their last modified date - every time the file is updated it's version number updates accordingly.&lt;/p&gt; &lt;ol class=&quot;code&quot;&gt; &lt;li&gt;&lt;code&gt;&amp;lt;?php&lt;/code&gt;&lt;/li&gt; &lt;li class=&quot;indent1&quot;&gt;&lt;code&gt;class Version {&lt;/code&gt;&lt;/li&gt; &lt;li class=&quot;indent2&quot;&gt;&lt;code&gt;private static $aLookup = array();&lt;/code&gt;&lt;/li&gt; &lt;li class=&quot;indent2&quot;&gt;&lt;code&gt;public static function Get($sFilename) {&lt;/code&gt;&lt;/li&gt; &lt;li class=&quot;indent3&quot;&gt;&lt;code&gt;if (!array_key_exists($sFilename, self::$aLookup)) {&lt;/code&gt;&lt;/li&gt; &lt;li class=&quot;indent4&quot;&gt;&lt;code&gt;$sRealPath = realpath($_SERVER['DOCUMENT_ROOT'] . &quot;/$sFilename&quot;);&lt;/code&gt;&lt;/li&gt; &lt;li class=&quot;indent4&quot;&gt;&lt;code&gt;if (file_exists($sRealPath) &amp;amp;&amp;amp; ($iTimestamp = filemtime($sRealPath))) {&lt;/code&gt;&lt;/li&gt; &lt;li class=&quot;indent5&quot;&gt;&lt;code&gt;self::$aLookup[$sFilename] = $iTimestamp;&lt;/code&gt;&lt;/li&gt; &lt;li class=&quot;indent5&quot;&gt;&lt;code&gt;$sFilename .= &quot;?v=$iTimestamp&quot;;&lt;/code&gt;&lt;/li&gt; &lt;li class=&quot;indent4&quot;&gt;&lt;code&gt;}&lt;/code&gt;&lt;/li&gt; &lt;li class=&quot;indent3&quot;&gt;&lt;code&gt;} else {&lt;/code&gt;&lt;/li&gt; &lt;li class=&quot;indent4&quot;&gt;&lt;code&gt;$sFilename .= '?v='.self::$aLookup[$sFilename];&lt;/code&gt;&lt;/li&gt; &lt;li class=&quot;indent3&quot;&gt;&lt;code&gt;}&lt;/code&gt;&lt;/li&gt; &lt;li class=&quot;indent3&quot;&gt;&lt;code&gt;return $sFilename;&lt;/code&gt;&lt;/li&gt; &lt;li class=&quot;indent2&quot;&gt;&lt;code&gt;}&lt;/code&gt;&lt;/li&gt; &lt;li class=&quot;indent2&quot;&gt;&lt;code&gt;public static function GetLink($sFilename) {&lt;/code&gt;&lt;/li&gt; &lt;li class=&quot;indent3&quot;&gt;&lt;code&gt;return '&amp;lt;link rel=&quot;stylesheet&quot; type=&quot;text/css&quot; href=&quot;'.self::Get($sFilename).'&quot;&amp;gt;';&lt;/code&gt;&lt;/li&gt; &lt;li class=&quot;indent2&quot;&gt;&lt;code&gt;}&lt;/code&gt;&lt;/li&gt; &lt;li class=&quot;indent2&quot;&gt;&lt;code&gt;public static function GetScript($sFilename) {&lt;/code&gt;&lt;/li&gt; &lt;li class=&quot;indent3&quot;&gt;&lt;code&gt;return '&amp;lt;script type=&quot;text/javascript&quot; src=&quot;'.self::Get($sFilename).'&quot;&amp;gt;&amp;lt;/script&amp;gt;';&lt;/code&gt;&lt;/li&gt; &lt;li class=&quot;indent2&quot;&gt;&lt;code&gt;}&lt;/code&gt;&lt;/li&gt; &lt;li class=&quot;indent2&quot;&gt;&lt;code&gt;public static function GetImage($sFilename, $iWidth, $iHeight, $sAlt = '') {&lt;/code&gt;&lt;/li&gt; &lt;li class=&quot;indent3&quot;&gt;&lt;code&gt;return sprintf('&amp;lt;img src=&quot;%s&quot; width=&quot;%d&quot; height=&quot;%d&quot; alt=&quot;%s&quot;&amp;gt;', self::Get($sFilename), $iWidth, $iHeight, $sAlt);&lt;/code&gt;&lt;/li&gt; &lt;li class=&quot;indent2&quot;&gt;&lt;code&gt;}&lt;/code&gt;&lt;/li&gt; &lt;li class=&quot;indent1&quot;&gt;&lt;code&gt;}&lt;/code&gt;&lt;/li&gt; &lt;li&gt;&lt;code&gt;?&amp;gt;&lt;/code&gt;&lt;/li&gt;
&lt;/ol&gt; &lt;p&gt;&lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://www.ejeliot.com/samples/version/version.inc.phps&quot;&gt;Download plain text version&lt;/a&gt; (&lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://www.ejeliot.com/samples/version/version-2.inc.phps&quot;&gt;Updated version to fix HTTP caching issues&lt;/a&gt;)&lt;/p&gt; &lt;p&gt;Using it is pretty simple - wrap the required function around the file path you'd normally have supplied to link, script or img tags.&lt;/p&gt; &lt;ol class=&quot;code&quot;&gt; &lt;li&gt;&lt;code&gt;&amp;lt;link rel=&quot;stylesheet&quot; type=&quot;text/css&quot; href=&quot;&amp;lt;?php echo Version::Get('/css/dark.css'); ?&amp;gt;&quot;&amp;gt;&lt;/code&gt;&lt;/li&gt;
&lt;/ol&gt; &lt;p&gt;In fact it's even easier than that - I've also provided some wrapper functions which make outputting link, script and img tags a little bit easier. The example above could be written more simply as follows:&lt;/p&gt; &lt;ol class=&quot;code&quot;&gt; &lt;li&gt;&lt;code&gt;&amp;lt;?php echo Version::GetLink('/css/dark.css'); ?&amp;gt;&lt;/code&gt;&lt;/li&gt;
&lt;/ol&gt;</description>
         <guid isPermaLink="false">gg6L8PuW3BGXJwFvjtzu1g_fa85cd9b96220430f4a36ff418d62ab3</guid>
         <pubDate>Mon, 07 Apr 2008 08:24:00 -0700</pubDate>
      </item>
      <item>
         <title>Collide-O-Scope</title>
         <link>http://feedproxy.google.com/~r/KentBrewster/~3/nQEOb_tN4aM/collide-o-scope</link>
         <description>&lt;style&gt;
canvas {float:right;margin:0 20px;border:2px solid #555;}
&lt;/style&gt;
&lt;p&gt;&lt;h3&gt;Here's a fun little vacation project, a canvas-powered Collide-O-Scope.&lt;/h3&gt;&lt;/p&gt;
 
&lt;p&gt;After being absolutely floored by some really impressive new HTML5 demos--see the &lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://9elements.com/io/projects/html5/canvas/&quot;&gt;9elements&lt;/a&gt; Twitter mash-up, for one--I figured it was time to give it a try myself. Here's the result.&lt;/p&gt;
&lt;p&gt;Assuming you're running a canvas-aware browser--see compatibility notes below-- you should be seeing several moving sets of randomly-generated circles, all projected with their seven possible translations and reflections. Each set has an X and Y vector; before each move we're running some very crude collision detection and altering those vectors if needed.&lt;/p&gt;
&lt;p&gt;While it's running, you can change things around by clicking anywhere inside the canvas. This will remove the oldest set of circles and add a new one where you click.&lt;/p&gt;
&lt;p&gt;The fuzzy/translucent effect comes from building up a number of very faint circles, on on top of the other. Depending on the colors, you'll see fuzzy blobs, sharp stained-glass sections, and other interesting stuff when two sets of circles overlap.&lt;/p&gt;
&lt;p&gt;At the moment I'm seeing smoothest results under Firefox in OSX, closely followed by Safari, with Chrome in last place. All three--and Opera 10--also run in Windows, but since I'm running Parallels I can't say how they compare to OSX, performance-wise.&lt;/p&gt;
&lt;p&gt;Sorry, no love for IE; I did try &lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://code.google.com/p/explorercanvas/&quot;&gt;excanvas&lt;/a&gt;, but it failed right away and I'm afraid I'm just not committed enough to caring about IE to investigate. (Hobby/pretty/vacation project, remember?)&lt;/p&gt;
&lt;h3&gt;Try It Out&lt;/h3&gt;
&lt;p&gt;If you'd like to try Collide-O-Scope, save this as an HTML file on your local directory and drag it into your browser:&lt;/p&gt;
&lt;pre class=&quot;source&quot;&gt;
&amp;lt;!DOCTYPE HTML&amp;gt;
&amp;lt;html&amp;gt;
&amp;lt;head&amp;gt;
&amp;lt;title&amp;gt;Collide-O-Scope&amp;lt;/title&amp;gt;
&amp;lt;style&amp;gt;
body { margin:0; padding:0; background-color:#666; text-align:center;
}
canvas { margin:50px auto 0; border:2px solid #ffa;
}
&amp;lt;/style&amp;gt;
&amp;lt;/head&amp;gt;
&amp;lt;body&amp;gt;
&amp;lt;script src=&quot;http://kentbrewster.com/collide-o-scope/collide.js&quot;&amp;gt;
{&quot;height&quot;:400, &quot;width&quot;:400}
&amp;lt;/script&amp;gt;
&amp;lt;/body&amp;gt;
&amp;lt;/html&amp;gt;
&lt;/pre&gt;
&lt;p&gt;Height and width go inside the &lt;code&gt;&amp;lt;SCRIPT&amp;gt;&lt;/code&gt; tag in curly brackets; for more on the techniques, please see any of my articles about &lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://kentbrewster.com/case-hardened-javascript&quot;&gt;Case-Hardened JavaScript&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Other valid configuration variables may be discovered by &lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://kentbrewster.com/collide-o-scope/collide.js&quot;&gt;viewing the script&lt;/a&gt; and looking in the &lt;code&gt;houseKeep&lt;/code&gt; function; you can change things like the number of circles on the page, the maximum number of rings per circle, ring thickness, ring opacity, background opacity, and canvas background color.&lt;/p&gt;
&lt;p&gt;As always, have fun with this, don't leech the script for production use on your site, and please let me know how it goes.&lt;/p&gt;</description>
         <guid isPermaLink="false">http://kentbrewster.com/collide-o-scope</guid>
         <pubDate>Fri, 04 Sep 2009 21:43:00 -0700</pubDate>
      </item>
      <item>
         <title>Fixing Twitter Replies</title>
         <link>http://feedproxy.google.com/~r/KentBrewster/~3/NfZnpyU_npU/twitter-fix-replies</link>
         <description>&lt;div id=&quot;s&quot; class=&quot;ftr&quot; style=&quot;float:right;margin-left:10px;&quot;&gt;
&lt;h3&gt;Hidden Tweets&lt;/h3&gt;
&lt;input id=&quot;q&quot; value=&quot;kentbrew&quot;/&gt;&lt;button id=&quot;b&quot;&gt;Go!&lt;/button&gt;
&lt;ul id=&quot;r&quot;&gt;&lt;/ul&gt;
&lt;/div&gt;
&lt;p&gt;A short while ago, something sucked the fun right out of &lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://twitter.com&quot;&gt;Twitter&lt;/a&gt;. All of a sudden, replies from people who I was following to people who were a) not me, or b) not people I was also following, &lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://mashable.com/2009/05/13/twitter-fixreplies/&quot;&gt;mysteriously quit showing up&lt;/a&gt;. Without knowing more about the underlying data structures I'm not certain I understand Twitter's explanation; it seems to me they'd have to go out of their way to find and remove tweets from people I'm following that were in reply to tweets from others that I'm not following, rather than just show me all the tweets from everybody I &lt;em&gt;am&lt;/em&gt; following.&lt;/p&gt;
&lt;p&gt;Anyway. I figured I'd go with it for a while and see if I noticed any difference ... and ... yeah, I do. Turns out the main way I found new, interesting people to follow was through those half-conversations. I haven't followed anybody new since replies broke, and find myself growing increasingly bored with Twitter.&lt;/p&gt;
&lt;h3&gt;Enter the Hack&lt;/h3&gt;
&lt;p&gt;At the top of this page, you'll see an entry box with my Twitter id filled in. If you click the button, you will see a list of tweets from people I'm following. Each of these tweets is the most recent one posted in reply to another Twitter user. If I'm not following that person, I won't see it when I look at my Twitter page. Right, some of these are false positives, for reasons mentioned below. I could clean it up, but I'm probably not going to do it. It's a hack, people. :)&lt;/p&gt;
&lt;p&gt;If you'd like to try it out and see some (probably not all) of what you're missing, fill in your Twitter screen name and click Go.&lt;/p&gt;
&lt;h3&gt;What This Won't Do&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Show all your friends. I'm calling the &lt;code&gt;&lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://apiwiki.twitter.com/Twitter-REST-API-Method%3A-statuses%C2%A0friends&quot;&gt;friends/status&lt;/a&gt;&lt;/code&gt; API five times to get the most current status from the last 500 users you followed; that's enough to show some of what you're missing. (Hey, while I have your ear ... please take a moment to think about the extra carbon you're causing Twitter to release into the atmosphere with all those follows you never actually pay attention to. 500 ought to be enough!)&lt;/li&gt;
&lt;li&gt;Show all the tweets you're missing. Sorry, it's only looking at the current status and reporting it as possibly hidden if it's listed as in-reply-to another Twitter user.&lt;/li&gt;
&lt;li&gt;Hide the tweets you're not missing. Again, sorry: since I'm only looking at the last 500 people you followed, I have no way of knowing what's in reply to the other 6000. (Again, please ... thin that ridiculous herd of follows, and help save Al3x's sanity.)&lt;/li&gt;
&lt;li&gt;Work on your site with a single line of JavaScript. Sorry, this is &lt;em&gt;not&lt;/em&gt; a case-hardened badge. (It might make an interesting Greasemonkey plug-in ... but somebody else gets to write it. Please keep in mind that you will quickly use up your 100 API calls in an hour if you bang on it too hard.)&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;Please Re-Tweet! :)&lt;/h3&gt;
&lt;p&gt;Twitter is much less useful to me without replies to friends I haven't met yet, so I really do hope they can fix it. Have fun with this, and if it's useful, kindly &lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://twitter.com/?status=Fixing+(Some)+Twitter+Replies,+from+@kentbrew:+http://bit.ly/kbftr+%23fixreplies&quot;&gt;tweet it up&lt;/a&gt; on Twitter. Thanks!&lt;/p&gt;
&lt;style&gt;
.ftr {margin:0;padding:3px;width:300px;border:2px solid #000;font:13px/1.2em tahoma, veranda, arial, helvetica, clean, sans-serif;}
.ftr a {cursor:pointer;text-decoration:none;}
.ftr a:hover{text-decoration:underline;}
.ftr img{float:left;height:24px;width:24px;border:1px solid black;margin:3px;}
.ftr cite, .ftr date{margin:0 0 0 4px;padding:0;display:block;font-style:normal;font-size:92%;line-height:12px;}
.ftr date:after{clear:both;&lt;/style&gt;
 &quot;;
echo $source;
echo &quot; &quot;;
include_once('/home/kentbrew/public_html/inc/footer.inc'); ?&amp;gt;</description>
         <guid isPermaLink="false">http://kentbrewster.com/twitter-fix-replies</guid>
         <pubDate>Wed, 27 May 2009 21:02:00 -0700</pubDate>
      </item>
      <item>
         <title>Twitter Search Badge</title>
         <link>http://feedproxy.google.com/~r/KentBrewster/~3/nOG-_hpfHTs/twitter-search-badge</link>
         <description>&lt;style&gt;
.floater {float:left;margin-right:5px;}
&lt;/style&gt;
&lt;p&gt;Twitter Search is turning out to be a very powerful force in real-time search. Instead of relying on a vaguely-defined, possibly-corrupt, almost-always-out-of-date algorhythm owned by somebody else, why not check out what your fellow Internet readers are marking as interesting and/or relevant? Here are three instances of the same search prototype, two with text queries and one with a &lt;code&gt;from:&lt;/code&gt; query, showing tweets from a single person.&lt;/p&gt;
&lt;div class=&quot;container&quot;&gt;
&lt;div class=&quot;floater&quot;&gt;
 
&lt;/div&gt;
&lt;div class=&quot;floater&quot;&gt;
 
&lt;/div&gt;
&lt;div class=&quot;floater&quot;&gt;
 
&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;If you'd like to try the Twitter Seach Badge on your site, include this bit of JavaScript wherever you want it to pop up:&lt;/p&gt;
&lt;pre&gt;
&amp;lt;script src=&quot;http://r8ar.com/tsb.js&quot;&amp;gt;&amp;lt;/script&amp;gt;
&lt;/pre&gt;
&lt;p&gt;The usual batch of configuration variables--height, width, etc--are available; to show a default search, do something like this:&lt;/p&gt;
&lt;pre&gt;
&amp;lt;script src=&quot;http://r8ar.com/tsb.js&quot;&amp;gt;{&quot;query&quot;:&quot;obama&quot;}&amp;lt;/script&amp;gt;
&amp;lt;script src=&quot;http://r8ar.com/tsb.js&quot;&amp;gt;{&quot;query&quot;:&quot;from:scobleizer&quot;}&amp;lt;/script&amp;gt;
&lt;/pre&gt;
&lt;p&gt;Right, obviously I need to combine this with &lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://kentbrewster.com/twitterati&quot;&gt;Twitterati&lt;/a&gt;. I'm just wishing the Twitter Search API had a way to come up with the most recent tweets by friends of &lt;code&gt;username&lt;/code&gt;. Will probably have to munge something together with Pipes to do that.&lt;/p&gt;
&lt;p&gt;Also still to come: Get More and Go Back links at the bottom.&lt;/p&gt;
&lt;p&gt;Here's my talk from the May 9th BayJax meetup, tracing the development process of this badge, which I wrote in a single afternoon. An older but much more detailed version of this presentation is online here, under &lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://kentbrewster.com/&quot;&gt;Case-Hardened Web Badges: The Live Version&lt;/a&gt;.&lt;/p&gt;
 
&lt;p&gt;&lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://kentbrewster.com/twitter-search-badge/preso.html&quot;&gt;Start Presentation in New Window&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;If you'd like me to present this, or something like it, or something completely unlike it (like Ajax security or OAuth or rolling your own API with Pipes) at your conference, please &lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://kentbrewster.com/contact/&quot;&gt;contact me&lt;/a&gt; and I'll see what I can do. As always, have fun and please let me know how it goes.&lt;/p&gt;</description>
         <guid isPermaLink="false">http://kentbrewster.com/twitter-search-badge</guid>
         <pubDate>Fri, 08 May 2009 09:46:00 -0700</pubDate>
      </item>
      <item>
         <title>Netflix Catalog API Explorer</title>
         <link>http://feedproxy.google.com/~r/KentBrewster/~3/-vdJo-dFYpc/netflix-api-explorer</link>
         <description>&lt;style&gt;#c {width:720px;}#c {text-align:right;}#c input {width:80%;}&lt;/style&gt;&lt;p&gt;&lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://netflix.com&quot;&gt;Netflix&lt;/a&gt;, in case you didn't know, is a marvelous place to rent movies and television series on DVD, and watch an increasing percentage online. Over the last ten years, Netflix has accumulated a treasure trove of information about movies and the people who make them, and has recently opened it all up with the Netflix Catalog API. (Full disclosure: yes, I work there, and yes, it's awesome.)&lt;/p&gt; &lt;p&gt;Here's a handy tool to help you get your feet wet without having to worry about OAuth.&lt;/p&gt; &lt;h3&gt;Before You Begin&lt;/h3&gt; &lt;p&gt;You'll need a developer account, from &lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://developer.netflix.com&quot;&gt;developer.netflix.com&lt;/a&gt;. Once you're signed up and logged in, the link to Consumer Key--below, to the left of the first text entry box--should take you right to the spot where you can copy your key and secret.&lt;/p&gt; &lt;p&gt;If you're feeling paranoid, please view source before clicking the Onwards! button. This thing just below that looks like a form really isn't a form, and is not going to submit your information anywhere except the Netflix API. The only reason why I'm using an all-client solution is so you, the developer, can actually try out your very own consumer key and shared secret, without me, the potentially-nefarious third party, ever actually knowing what they are.&lt;/p&gt; &lt;h3&gt;Try Your Queries Right Here&lt;/h3&gt; &lt;div id=&quot;c&quot;&gt; &lt;p&gt;&lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://developer.netflix.com/apps/mykeys&quot;&gt;Consumer Key&lt;/a&gt;: &lt;input id=&quot;k&quot; value=&quot;&quot;/&gt;&lt;/p&gt; &lt;p&gt;Shared Secret: &lt;input id=&quot;s&quot; value=&quot;&quot;/&gt;&lt;/p&gt; &lt;p&gt;Query: &lt;input id=&quot;q&quot; value=&quot;http://api.netflix.com/catalog/titles/?term=fargo&quot;/&gt;&lt;/p&gt; &lt;p&gt;Got your consumer key and shared secret filled in? Click me: &lt;button id=&quot;b&quot;&gt;Onwards!&lt;/button&gt;&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;&lt;a rel=&quot;nofollow&quot; id=&quot;u&quot; style=&quot;display:none;&quot;&gt;Your OAuth-Signed URL&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt; &lt;/div&gt; &lt;h3&gt;Sample Queries (Click to Try)&lt;/h3&gt; &lt;ul id=&quot;x&quot;&gt; &lt;li&gt;Autocomplete search results for the string &quot;mcdo&quot;:&lt;br /&gt;&lt;code&gt;&lt;a rel=&quot;nofollow&quot;&gt;http://api.netflix.com/catalog/titles/autocomplete?term=mcdo&lt;/a&gt;&lt;/code&gt;&lt;/li&gt; &lt;li&gt;Find the first Frances in the People section:&lt;br /&gt;&lt;code&gt;&lt;a rel=&quot;nofollow&quot;&gt;http://api.netflix.com/catalog/people?term=Frances&amp;max_results=1&lt;/a&gt;&lt;/code&gt;&lt;/li&gt; &lt;li&gt;Zoom in on Frances McDormand:&lt;br /&gt;&lt;code&gt;&lt;a rel=&quot;nofollow&quot;&gt;http://api.netflix.com/catalog/people/61544&lt;/a&gt;&lt;/code&gt;&lt;/li&gt; &lt;li&gt;See Franceses 2 through 10:&lt;br /&gt;&lt;code&gt;&lt;a rel=&quot;nofollow&quot;&gt;http://api.netflix.com/catalog/people?term=Frances&amp;start_index=1&amp;max_results=9&lt;/a&gt;&lt;/code&gt;&lt;/li&gt; &lt;li&gt;Frances McDormand's filmography, with synopses:&lt;br /&gt;&lt;code&gt;&lt;a rel=&quot;nofollow&quot;&gt;http://api.netflix.com/catalog/people/61544/filmography?expand=synopsis&lt;/a&gt;&lt;/code&gt;&lt;/li&gt; &lt;li&gt;Zoom in on Fargo:&lt;br /&gt;&lt;code&gt;&lt;a rel=&quot;nofollow&quot;&gt;http://api.netflix.com/catalog/titles/movies/493387&lt;/a&gt;&lt;/code&gt;&lt;/li&gt; &lt;li&gt;Fargo again, with expanded cast and synopsis:&lt;br /&gt;&lt;code&gt;&lt;a rel=&quot;nofollow&quot;&gt;http://api.netflix.com/catalog/titles/movies/493387?expand=cast,synopsis&lt;/a&gt;&lt;/code&gt;&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;These are only a few examples; please see the &lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://developer.netflix.com/docs/REST_API_Reference&quot;&gt;REST API Reference&lt;/a&gt; for detailed information.&lt;/p&gt; &lt;h3&gt;Things to Do and Notice&lt;/h3&gt; &lt;ul&gt; &lt;li&gt;When your results come back, just about any link that starts with &lt;code&gt;http://api.netflix.com/catalog&lt;/code&gt; can be copied and pasted right back into the query blank for further exploration.&lt;/li&gt; &lt;li&gt;A link to your OAuth-signed URL will magically appear under the iframe containing your results. If you click this it ought to open your results in a new page, so you can see exactly what OAuth did to your request string. This is very, very handy when you're wrestling with some of the more arcane aspects of the API, such as what needs to be URL-encoded.&lt;/li&gt; &lt;li&gt;Use Netflix's handy &lt;code&gt;expand&lt;/code&gt; parameter to avoid extra calls to the API. Any of the &lt;code&gt;link&lt;/code&gt; attributes in the main tree should be expandable; details are in the API docs, which I am currently in the process of refactoring.&lt;/li&gt; &lt;li&gt;To try out version 1.5 of the Netflix API, add &lt;code&gt;v=1.5&lt;/code&gt; to any query. Please note that &lt;code&gt;expand&lt;/code&gt; behaves differently in version 1.5.&lt;/li&gt; &lt;/ul&gt; &lt;h3&gt;Don't Forget to Break It!&lt;/h3&gt; &lt;p&gt;No, seriously. This is critical; you need to know what happens when things go wrong. Change your key or secret, or enter an URL that doesn't compute, and make note of the errors you get back.&lt;/p&gt; &lt;h3&gt;Bad Ideas&lt;/h3&gt; &lt;ul&gt; &lt;li&gt;&lt;strong&gt;Trying to retrieve the entire catalog.&lt;/strong&gt; (Okay, I admit it: I tried this myself. The resulting bolus of data choked my browser, and I had to reboot and recover some lost stuff that I hadn't saved.) Client apps should never need the entire catalog; if you are thinking about doing this, you are doing it Wrong.&lt;/li&gt; &lt;li&gt;&lt;strong&gt;Using term search to power autocomplete.&lt;/strong&gt; That's what &lt;code&gt;/catalog/titles/autocomplete&lt;/code&gt; is for, folks; it's even been left free of OAuth requirements so people banging on it won't use up your daily quota of API calls.&lt;/li&gt; &lt;li&gt;&lt;strong&gt;Putting this script into production anywhere.&lt;/strong&gt; Although OAuth calls can be made using nothing but JavaScript, doing so will reveal your consumer key and shared secret on every call, which could lead to trouble if either item is hijacked and used by someone who is not you.&lt;/li&gt; &lt;/ul&gt; &lt;h3&gt;Other Important Resources&lt;/h3&gt; &lt;ul&gt; &lt;li&gt;If you'd like to play around with OAuth parameters, see the &lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://developer.netflix.com/resources/OAuthTest&quot;&gt;OAuth Test Page&lt;/a&gt;.&lt;/li&gt; &lt;li&gt;To run signed-in calls to the Netflix API--accessing things like a specific user's queue--you'll want &lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://developer.netflix.com/files/&quot;&gt;Flixo&lt;/a&gt;.&lt;/li&gt; &lt;li&gt;Although it feels very GOOG-centric, the &lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://googlecodesamples.com/oauth_playground/&quot;&gt;OAuth Playground&lt;/a&gt; has a spot under &quot;Choose Your Scope&quot; where you can enter any OAuth endpoint. Netflix works there.&lt;/li&gt; &lt;/ul&gt; &lt;h3&gt;The JavaScript Source&lt;/h3&gt; &lt;p&gt;For the morbidly curious, here's how I got client-side OAuth to work in eighty lines of JavaScript. It may be worth looking at if you're a throwback like me who refuses to use a library he doesn't understand. The heavy lifting happens at the bottom of the script, from &lt;code&gt;oAuthEscape&lt;/code&gt; on down, with much help from &lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://pajhome.org.uk/crypt/md5/sha1.js&quot;&gt;Paul Johnston's HMAC-SHA1 routine&lt;/a&gt;.&lt;/p&gt;
&lt;pre class=&quot;source&quot;&gt;

 
&lt;/pre&gt; &lt;p&gt;If you'd like to learn more about the various snakes that bit me while I was figuring it out, please see &lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://kentbrewster.com/oauth-confessions&quot;&gt;True OAuth Confessions, or Why My Hand-Rolled Calls All Blew Chunks&lt;/a&gt;.&lt;/p&gt; &lt;p&gt;Have fun, please let me know how it goes, and don't forget to read the documentation, at &lt;code&gt;&lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://developer.netflix.com/&quot;&gt;http://developer.netflix.com/&lt;/a&gt;&lt;/code&gt;. It will be better soon, I promise! :)&lt;/p&gt;

 &quot;;
echo $source;
echo &quot; &quot;;
include_once('/home/kentbrew/public_html/inc/footer.inc'); ?&amp;gt;</description>
         <guid isPermaLink="false">http://kentbrewster.com/netflix-api-explorer</guid>
         <pubDate>Tue, 28 Apr 2009 17:13:00 -0700</pubDate>
      </item>
      <item>
         <title>True OAuth Confessions</title>
         <link>http://feedproxy.google.com/~r/KentBrewster/~3/286s5aS2YZY/oauth-confessions</link>
         <description>&lt;p&gt;I'm settling in at Netflix and starting to work my way through the developer docs. One of the main concerns we're seeing from outside developers is getting that first OAuth call to work. Here, in an effort to reassure my fellow noobs that they're not crazy, is my tale of OAuth woe:&lt;/p&gt;
&lt;p&gt;When I &lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://kentbrewster.com/oauth-baby-steps&quot;&gt;first encountered OAuth&lt;/a&gt; I bounced off the &lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://oauth.net/core/1.0&quot;&gt;spec&lt;/a&gt; and a couple of &lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://oauth.googlecode.com/svn/code/javascript/oauth.js&quot;&gt;libraries&lt;/a&gt;, which seem to be documented in a language created specifically to make guys like me give up in disgust.&lt;/p&gt;
&lt;p&gt;Backup plan: I cracked into a couple of URL returns with Firebug, thought I understood what was going on, and plunged blindly in. (Famous last words: &quot;It's just a string, right? How hard could it possibly be?&quot;)&lt;/p&gt;
&lt;p&gt;My real mistake: not just blindly trusting the libraries to do the right thing. Seriously. Unless you've got the same thing wrong with you that I have with me and you absolutely cannot stand the idea of using something you don't fully understand, stop here and just go plug in a library.&lt;/p&gt;
&lt;p&gt;So. Here begins my top ten list of horrible mistakes made while trying to reverse-engineer OAuth:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;My Timestamp was Stale&lt;/strong&gt;&lt;br /&gt;
Unless it's only a few minutes old, the URL somebody else generated isn't going to work. And forget about trying to copy and paste the one they show in the docs. If you're working in JavaScript, your client's clock needs to be within ten minutes of your API's clock. (WinXP under Parallels seems to lose track of time every once in a while; cue the sound of Nelson Muntz from The Simpsons: &quot;Ha-hah!&quot;)&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;The Parameters in my Signature Base String were Out of Alphabetical Order&lt;/strong&gt;&lt;br /&gt;
Note to self: &lt;code&gt;oauth_signature_method&lt;/code&gt; comes BEFORE &lt;code&gt;oauth_timestamp&lt;/code&gt;, and AFTER &lt;code&gt;oauth_nonce&lt;/code&gt;. Parameters like &lt;code&gt;foo&lt;/code&gt; and &lt;code&gt;baz&lt;/code&gt; and &lt;code&gt;qux&lt;/code&gt; might show up before or afterwards. Or during, depending on how psychotic the API you're trying to hit turns out to be.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;I Forgot a Question-Mark between my Request and my OAuth Payload&lt;/strong&gt;&lt;br /&gt;
Here's where you do NOT want an ampersand. You'll go blind trying to spot it.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;I Didn't URL-Encode my Signature&lt;/strong&gt;&lt;br /&gt;
Just because it came back in base-64 from my HMAC-SHA1 function didn't make it safe to fire off; there are plus-signs and equals-signs and other unsavory characters in many base-64 strings, and they all needed to be encoded.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;I Didn't URL-Encode All Illegal Characters&lt;/strong&gt;&lt;br /&gt;
Right, see, I was initially doing this with JavaScript, and &lt;code&gt;uriEncodeComponent&lt;/code&gt; turned out not to fix exclamation points, asterisks, single-quotes, or parentheses.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;I URL-Encoded the Ampersands Separating my Method, URL, and Request Parameters&lt;/strong&gt;&lt;br /&gt;
The server needs those raw ampersands, so it can tell where to split the string you sent.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;I Didn't Append an Ampersand to my Consumer Secret to Make my Signature Key&lt;/strong&gt;&lt;br /&gt;
Another picky ampersand-related detail: when signing a request without a token secret I STILL needed to add an ampersand to the end of my consumer secret.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;I Used the Same Nonce, Over and Over and Over Again&lt;/strong&gt;&lt;br /&gt;
Turns out there is a special circle of Error 401 Hell reserved for people who re-use their nonces; this makes sense, if you think about the sort of replay attacks the spec is designed to prevent. Naturally you would need to READ the spec before thinking about this.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;I Generated a Random Nonce, but (you guessed it) Failed to URL-Encode It&lt;/strong&gt;&lt;br /&gt;
No need to be fancy with this; just pick a random 16-digit number. Don't (for instance) use every possible printable character.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;And, Finally: I URL-Encoded my Signature Key&lt;/strong&gt;&lt;br /&gt;
Yeah, I really did do this. It took days to unscrew. Not recommended.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Anyone else have something to confess? Let's hear it; it will be good for your soul, and will help our fellow pilgrims not to fall down the same holes we did.&lt;/p&gt;</description>
         <guid isPermaLink="false">http://kentbrewster.com/oauth-confessions</guid>
         <pubDate>Mon, 27 Apr 2009 15:08:00 -0700</pubDate>
      </item>
      <item>
         <title>Amazon Wish Lists Are Dreadfully Insecure</title>
         <link>http://feedproxy.google.com/~r/KentBrewster/~3/eDES9Na6MkE/amazon-wish-lists-are-dreadfully-insecure</link>
         <description>&lt;h3&gt;Updated 3/27/2009, 10:01PDT: looks like this may have been fixed a few minutes ago. Read on, to learn more about what was happening.&lt;/h3&gt;
&lt;p&gt;Old friends may remember the &lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://blog.programmableweb.com/2008/03/07/are-you-logged-into-google/&quot;&gt;How to Tell if a User is Signed In to Service X&lt;/a&gt; series, which ended last year around this time. As you can see from the comments in &lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://kentbrewster.com/patching-privacy-leaks/&quot;&gt;Patching Privacy Leaks&lt;/a&gt;, I advised users to sign out of Amazon.com on 17 October 2008, but did not say why.&lt;/p&gt;
&lt;p&gt;Six months and multiple warnings later, nothing's been done. So here it is:&lt;/p&gt;
&lt;button&gt;Add an Item to your Amazon Wishlist&lt;/button&gt;
&lt;p id=&quot;amazonResults&quot;&gt;If you are signed in to the United States version of Amazon.com and have a wish list, the button should add an item. You'll see an alert with a success or failure message, and then this paragraph will change to tell you what happened and where to go to see it. If you're using Firefox or IE, we will be able to determine your Amazon login status, by watching &lt;code&gt;onError&lt;/code&gt;. If all else fails, we will assume after a few seconds of inactivity that something went wrong.&lt;/p&gt;
&lt;p&gt;I'm not sure what will happen if you have multiple lists or if you delete your wish list. Taking your wish list private will make it invisible to the bit that shows your name, but will NOT stop the item add from happening.&lt;/p&gt;
&lt;h3&gt;How It Works&lt;/h3&gt;
&lt;p&gt;By examining the source of Amazon's &lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://www.amazon.com/gp/wishlist/get-button/&quot;&gt;Universal Wish List toolbar bookmarklet&lt;/a&gt;, we find something suspicious: an &lt;code&gt;HTTP GET&lt;/code&gt; that seems to modify data on behalf of the signed-in Amazon user. This is trouble, since Amazon is depending only on browser cookies to verify user identity. Anyone can create an URL, like this:&lt;/p&gt;
&lt;pre&gt;http://www.amazon.com/gp/wishlist/add/ref=wl_bm-add
?submit=1&amp;operation=add&amp;mode=JS&amp;priceInput=&amp;id=
&amp;imageUrl.0=http%3A%2F%2Fi2.ytimg.com%2Fvi%2FE62DXiL_8Vs%2Fdefault.jpg
&amp;name.0=Raccoon%20Party
&amp;itemComment.0=amazon%20wishlists%20are%20dreadfully%20insecure
&amp;productUrl.0=http%3A%2F%2Fwww.youtube.com%2Fwatch%21v%3eDeQ1DN7n2Eg
&lt;/pre&gt;
&lt;p&gt;... and fire it off on behalf of the signed-in user. Here I'm being polite and requiring the user to click a button, but it would be trivial to list it as the &lt;code&gt;SRC&lt;/code&gt; attribute of a &lt;code&gt;SCRIPT&lt;/code&gt; or &lt;code&gt;IMG&lt;/code&gt; tag.&lt;/p&gt;
&lt;h3&gt;Data Returned from Amazon&lt;/h3&gt;
&lt;pre&gt;AUWLBook.results('SUCC', 'Wish List',
'http://www.amazon.com/registry/wishlist/JWMG6ATT26YQ/ref=wl_bm-view-list');&lt;/pre&gt;
&lt;p&gt;This is very helpful: it gives you back a &lt;code&gt;SUCC&lt;/code&gt; or &lt;code&gt;FAIL&lt;/code&gt; message, the title of the victim's wish list, and an URL pointing back to it, whether or not the victim has market his list as private. If the list is public, determining the victim's name is trivial; &lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://pipes.yahoo.com/kentbrew/amazon_getusernamefromwishlistid&quot;&gt;running the wish list through YQL and trimming the result with Pipes&lt;/a&gt; spits it right out.&lt;/p&gt;
&lt;p&gt;I'm not going to go into great detail about how the JavaScript behind the exploit works; it's pretty self-explanatory. Feel free to view source and poke at it yourself, if you like.&lt;/p&gt;
&lt;h3&gt;Why It's Scary&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;I can think of lots of evil things to do with this, from the crude (add a bunch of porno links to your victim's wish list and send it to his boss or his wife or his mother) to the obvious (causing any visitor to my site to instantly wish for my book, over and over and over again) to subtle things like gray-hat SEO, in which links quietly stack up in thousands of public wish lists and change search engine results.&lt;/li&gt;
&lt;li&gt;Possibilities for clandestine data mining--many people add their birthdays and home locations to their wish lists--abound. Once I know your name, home town, and birthday, I have a fair number of the items most commonly used as security questions for password recovery.&lt;/li&gt;
&lt;li&gt;Although I haven't documented it here, there is at least one link on the user's wish list that will save a change to its configuration in response to a GET, and not just add an item. This is very, very bad.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The bottom line: Amazon never told their users that wish lists are actually online presence indicators and can be used invisibly to gather data about them wherever they go.&lt;/p&gt;
&lt;h3&gt;Lessons Learned&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Never use &lt;code&gt;GET&lt;/code&gt; to modify data on behalf of the user.&lt;/li&gt;
&lt;li&gt;Don't give back live, executable JavaScript wrapped in easily-intercepted callbacks.&lt;/li&gt;
&lt;li&gt;Returning HTML to signed-out users and JSON to signed-in users allows curious operators to determine the user's sign-in status by watching &lt;code&gt;window.onerror&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Shipping a toolbar bookmarklet that changes data on behalf of a signed-in user is probably not a great idea; now that it's broken, everybody who's installed it will have to either re-install it or quit using it.&lt;/li&gt;
&lt;li&gt;Have a clearly marked path for reporting security holes, listen, and be extremely responsive!&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;Thank You&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Last-minute testers: Norm, Cyn, Ryan.&lt;/li&gt;
&lt;li&gt;Those guys who do the thing in that place I used to work, who tried multiple times to get Amazon to fix this. They are heroes; I wish people would listen harder when they speak up.&lt;/li&gt;
&lt;/ul&gt;
</description>
         <guid isPermaLink="false">http://kentbrewster.com/amazon-wish-lists-are-dreadfully-insecure</guid>
         <pubDate>Wed, 25 Mar 2009 08:26:00 -0700</pubDate>
      </item>
      <item>
         <title>Bad JavaScript Advice Filter</title>
         <link>http://feedproxy.google.com/~r/KentBrewster/~3/VmgS-mfcxM8/bad-javascript-advice-filter</link>
         <description>&lt;h3&gt;When somebody comes to me and says &quot;I want to learn HTML,&quot; I always ask &quot;Why?&quot;&lt;/h3&gt;
&lt;p&gt;&lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://gallery.search.yahoo.com/application?smid=Ghw.s&quot;&gt;&lt;img src=&quot;http://l.yimg.com/i/searchmonkey/logoImage123627792437313.png&quot; style=&quot;border:1px solid black;float:left;margin-right:20px;&quot;/&gt;&lt;/a&gt; Don't get me wrong; unlike writing, I don't believe that anyone who can be discouraged from coding should be. Web programming is a fine thing to know, but it's very hard to learn just for the sake of learning it. Big topic, lots of pitfalls, you get the idea. So if I'm talking to someone who just has a vague idea that it would be cool to know how to do this stuff, I make vague comforting noises and try not to offer advice.&lt;/p&gt;
&lt;p&gt;But if the person talking to me pops back with &quot;I want to build a Web site for Specific Reason X,&quot; we're off and running. It's much easier to learn the tiny subset of knowledge necessary to get your specific project off the ground than it is to gain general background knowledge enough to do anything you want, at some distant point in the future.&lt;/p&gt;
&lt;p&gt;After representing Yahoo! at several University Hack Days and watching superstar Monkey Wrangler &lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://paulisageek.blogspot.com/&quot;&gt;Paul Tarjan&lt;/a&gt;--fresh out of Stanford, first real job, builds a game-changing search app for Yahoo, quick, eat him now while his bones are still soft--I was fascinated. But I didn't jump straight in with &lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://gallery.search.yahoo.com&quot;&gt;Searchmonkey&lt;/a&gt;, because I couldn't think of anything interesting to do with it.&lt;/p&gt;
&lt;p&gt;That changed this morning, when I was poking around looking for some embarassingly basic JavaScript advice. (I'm lazy, and ignorant, and figure &quot;why waste space in my brain if the cloud is available to store all that knowledge?&quot;)&lt;/p&gt;
&lt;p&gt;News flash: there is a crapload of really bad information out there. It's a) old, b) misguided, and c) wrapped in banner ads or sign-in-to-see-the-answer bait-and-switch gotchas. Unfortunately, it's been there a long time, and has many supporting links and other SEO-fu around it, so it tends to sort to the top.&lt;/p&gt;
&lt;p&gt;I click into this junk a lot, and it bothers me.&lt;/p&gt;
&lt;h3&gt;Enter the Monkey.&lt;/h3&gt;
&lt;p&gt;With a simple set of URL filters, I was able to build bad.js, a &lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://gallery.search.yahoo.com/application?smid=Ghw.s&quot;&gt;Searchmonkey add-on for Yahoo! Search&lt;/a&gt; that warns me away from all those lovely canned scripts and talking banner ads from 1997. Bad.js was simple to build, easy to publish, and generally a joy to do; if you want to play, I strongly recommend checking out Searchmonkey, at &lt;code&gt;&lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://gallery.search.yahoo.com&quot;&gt;http://gallery.search.yahoo.com&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Suggestions for other URLs will be gratefully accepted; please leave them on the Searchmonkey app's Comments tab, so I can find them all in one place. (Lazy, remember?)&lt;/p&gt;&lt;/code&gt;</description>
         <guid isPermaLink="false">http://kentbrewster.com/bad-javascript-advice-filter</guid>
         <pubDate>Thu, 05 Mar 2009 15:55:00 -0800</pubDate>
      </item>
      <item>
         <title>GitHub Social Badge</title>
         <link>http://feedproxy.google.com/~r/KentBrewster/~3/L333VYtTf1c/github-badge</link>
         <description>&lt;div style=&quot;float:right;margin-left:10px;&quot;&gt;
 
&lt;/div&gt;
&lt;p&gt;As usual I'm late for the bandwagon. Here's my very first &lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://github.com/kentbrew&quot;&gt;GitHub&lt;/a&gt; project, a case-hardened badge that allows a certain amount of surfing around between GitHub repositories, owners, and watchers.&lt;/p&gt;
&lt;h3&gt;Things to Do and Notice&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;In Projects view, click the arrrow to open up details. The top project will default to open.&lt;/li&gt;
&lt;li&gt;Click between Projects and Following to see the user's repositories and other users he or she is following.&lt;/li&gt;
&lt;li&gt;Click a user icon to switch over.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;How It Works&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;This badge relies on techniques previously documented in &lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://kentbrewster.com/badges&quot;&gt;Case-Hardened JavaScript&lt;/a&gt;; please look there for technical details.&lt;/li&gt;
&lt;li&gt;For Projects we are looking at the GitHub API, documented here:&lt;br /&gt;&lt;code&gt;&lt;a rel=&quot;nofollow&quot; target=&quot;_blank&quot; href=&quot;http://github.com/guides/the-github-api&quot;&gt;http://github.com/guides/the-github-api&lt;/a&gt;&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;For Following we are using the spiffy new YQL module on Pipes to gently ping the user's home page on GitHub, grab only the user names and avatars, and return them ready to go. Hopefully the official API will include this soon; for now, it's a very scraping, since Pipes is caching requests.&lt;/li&gt;
&lt;li&gt;Here we see the badge pointed at the GitHub profile belonging to Mark Norman Francis. Norm has interesting projects and is following some interesting people, so he's my test account. Please change it to whoever you like.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;Want to Try It Out?&lt;/h3&gt;
&lt;p&gt;Paste this into the body of your document, right where you want the badge to show up:&lt;/p&gt;
&lt;pre&gt;&amp;lt;script src=&quot;http://kentbrewster.com/github-badge/behavior.js&quot;&amp;gt;{&quot;user&quot;:&quot;norm&quot;}&amp;lt;/script&amp;gt;&lt;/pre&gt;
&lt;p&gt;Please do NOT point to either of my copies of the script (here or on GitHub) for your production site. That would be Bad. :)&lt;/p&gt;
&lt;h3&gt;Two Ways to Grab the Source&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Fork the known-to-be-working version from GitHub, here:&lt;br /&gt;&lt;code&gt;&lt;a rel=&quot;nofollow&quot; target