Ubuntu 9.04 boots in 7.83 seconds!

Recently I treated myself to a solid-state drive (SSD). That’s essentially a hard-drive made out of memory chips. I bought the Intel X25-E Extreme, which uses faster single-level cell (SLC) memory chips instead of slower multi-level cell (MLC) memory chips.

I wanted to put the drive through its paces, so I decided to see how fast I could boot Ubuntu and start Firefox. It turns out that Ubuntu 9.04, code-named Jaunty Jackalope, is just a few days away, and one of the features listed is “significantly improved boot performance.” Perfect! I installed Ubuntu 8.10 from a CD and then followed the incredibly easy instructions to upgrade to the beta of 9.04.

So how fast did Ubuntu 9.04 boot with a solid-state drive? Really freaking fast. Like, “I can’t believe it’s already done” fast. Well, here, watch for yourself:

Total boot time from pressing power to Firefox loaded was about 22.5 seconds, with about 5 seconds of BIOS display on a Thinkpad. Subtracting out the Thinkpad BIOS display time, that means that Ubuntu 9.04 booted into Firefox in about 17.5 seconds. I think I’m going to have a lot of fun with this hard drive. Oh, and Ubuntu 9.04 looks really interesting too. :)

For the folks that are curious, I changed the GRUB boot loader time out from three seconds to zero, enabled automatic login to my account, then I added Firefox to default list of startup services.

Added: I collected a couple boot charts by using bootchart. As Ryan said in a comment, I ran sudo apt-get install pybootchartgui bootchart , then rebooted, then collected the image in /var/log/bootchart . If I’m reading the images correctly, it’s claiming 8.67 seconds for one boot-up and 8.69 seconds for the other boot-up.

Added: Okay, I reinstalled Ubuntu 9.04 so I could use ext4 and it shaved almost a second off the boot time! Check out this image which shows a 7.83 second boot time. :)

Hacking Google: Retro Links Revives Old Google Feature

Google sometimes turns off features. One such feature that I remember fondly is that at the bottom of Google’s search results, we offered nine other search engine suggestions. The idea was if you didn’t find what you were searching for on Google, you could click on the other links and easily run the same search somewhere else. Luckily, due to an April Fool’s joke about the Mentalplex, you can still see what these links looked like:

Other search engines in 2000

Many of these search engines consolidated or changed focus over time. Plus I’m guessing that every search engine in the world wanted to be on the list, which must have been really annoying for whichever Google person had to maintain that list of links. I think the list of other search engines dwindled down and eventually Google just turned the feature off.

Recently I was describing this feature to Tiffany Lane, another engineer at Google, and she had a great idea. Why not recreate this search feature on Google with modern search engines and websites? Because of the pain of maintaining an “official” list, we probably couldn’t turn this on for every user (plus not every user wants a lot of extra links added to their search results). But why not provide a completely unofficial option that people could install?

Thus was born Retro Links, which is a Greasemonkey script to add new search options to Google’s search results page. When Retro Links is installed, it looks like this:

Retro Links

Unlike the original feature, Retro Links lets you select which search engines to show from 42 different websites and search engines, then saves those preferences. It’s also very easy to add a new search engine in the JavaScript file.

Installation

Get Retro Links here: http://www.mattcutts.com/retrolinks/retrolinks.user.js

To install Retro Links you will need to be using Firefox and have Greasemonkey installed. Once Greasemonkey is running then you can click on the link above and you will be prompted to install the script. To see that it is working you can do a Google search – the links will be inserted near the bottom of the Google search results page.

Configuration

Configuring Retro Links is really simple. Suppose that you want to change the default Amazon link to search on Yelp. Just click on the [+] link to the right of the search engines and select Yelp from the drop-down box:

Changing search engines in Retro Links

When you’re happy with your search engines, click the “Save” button to save your preferences.

Questions

What if the site I want is not one of the 42 options?
You can add more sites to the options by making a simple code change. To edit the code go to Tools -> Greasemonkey -> Manage User Scripts, select Retro Links and click the Edit button. Simply add the name and url of the new site to the RL_LINK_OPTIONS array, following the examples that are already there.

How do I turn on/off the update notification?
The script checks to see if a newer version is available once per day. If an update is available a red box will appear in the bottom right corner of the page with a link to download the latest version. If you want to stop checking for updates go to Tools -> Greasemonkey -> User Script Commands and select Retro Links -> Never check for updates. To start checking again select Retro Links -> Check for updates daily.

Disclaimer

Finally, Tiffany wanted to make sure that I included this quick disclaimer: “Retro Links is not an official Google project. I chose which links to include based on my personal preferences and web surfing habits. These decisions do not represent the opinions of my employer.” Tiffany, thanks for writing this great script!

DroboCare from Drobo: bleah

I bought a Drobo about a year ago. Recently I got this pop-up window:

DroboCare warranty service by Drobo

Wait a second — I bought this storage device, and now want me to extend my license “to continue to receive the latest updates”? If you go to the url mentioned in the pop-up, you see that for $49 for a year’s coverage, you get

Continued access to software updates to Drobo Dashboard, Drobo Firmware and DroboShare Firmware including performance enhancements and new features.

Both the program pop-up and the web page imply that I need to pay $49 to continue to get firmware updates. That’s extremely uncool. The ironic part is that apparently Drobo changed their mind in February and they won’t make you pay for firmware updates now. It’s been a month; why does the DroboCare web page still imply that you have to pay $49/year for firmware updates? They need to fix that ASAP, because people appear to be confused by the language.

Let me tell you a little story: back in the 90s, before eBay existed, I was a poor college student who wanted to connect a CD recorder to his computer. I bought a used Adaptec SCSI card over Usenet. When the SCSI card arrived, the four floppy disks of driver software were scrambled. When I tried to get drivers from Adaptec, I learned that Adaptec charged for the drivers for that SCSI card. I never bought another Adaptec product again. The End.

So I don’t plan to buy any more Drobos in the future. Why would I buy from a company that tried to charge me for firmware updates for my consumer hardware? Sure, Drobo changed their mind after people complained, but the fact that Drobo even considered it will make me avoid them in the future.

Update: read this blog comment by Jillian Mansolf from Drobo. Evidently Drobo’s Sarbanes-Oxley auditors classified Drobo as a software company. The auditors “wanted us to recognize revenue for Drobo over the ‘life’ of the warranty (forever) if we included performance enhancements through free software updates.” DroboCare only pertains to hardware as of January, so a future version of the DroboDashboard software will remove this pop-up. Read the comment for more about this from Drobo.

Write to a Google Spreadsheet from a Python script

Suppose you want to write to a Google Spreadsheet from a Python script. Here’s an example spreadsheet that you might want to update from a script:

Example spreadsheet

I did some searching and found this page, which quickly led me to the Python Developer’s Guide for the Google Spreadsheet API.

There’s a simple “Getting started with Gdata and Python” page. The upshot is 1) make sure you have a recent version of Python (e.g. 2.5 or higher), then 2) install the Google Data Library. The commands I used were pretty much

mkdir ~/gdata
(download the latest Google data Python library into the ~/gdata directory)
unzip gdata.py-1.2.4.zip (or whatever version you downloaded)
sudo ./setup.py install

That’s it. You can test that everything installed fine by running “./tests/run_data_tests.py” to verify that the tests all pass. The program “./samples/docs/docs_example.py” lets you list all of your Google Spreadsheets, for example. An extremely useful program that lets you insert rows right into a spreadsheet is “./samples/spreadsheets/spreadsheetExample.py” and someone has also got a really nice example of uploading a machine’s dynamic IP address to a spreadsheet.

The most painful thing is that InsertRow() must be called with a spreadsheet key and a worksheet key. If you find out those values, you could hardcode them into the script and probably cut the size of the script in half. Or you could just look in the url to see the key value. That’s what I did. So here’s an miniature example script to write to a Google Spreadsheet from a Python script:


#!/usr/bin/python

import time
import gdata.spreadsheet.service

email = 'youraccount@gmail.com'
password = 'yourpassword'
weight = '180'
# Find this value in the url with 'key=XXX' and copy XXX below
spreadsheet_key = 'pRoiw3us3wh1FyEip46wYtW'
# All spreadsheets have worksheets. I think worksheet #1 by default always
# has a value of 'od6'
worksheet_id = 'od6'

spr_client = gdata.spreadsheet.service.SpreadsheetsService()
spr_client.email = email
spr_client.password = password
spr_client.source = 'Example Spreadsheet Writing Application'
spr_client.ProgrammaticLogin()

# Prepare the dictionary to write
dict = {}
dict['date'] = time.strftime('%m/%d/%Y')
dict['time'] = time.strftime('%H:%M:%S')
dict['weight'] = weight
print dict

entry = spr_client.InsertRow(dict, spreadsheet_key, worksheet_id)
if isinstance(entry, gdata.spreadsheet.SpreadsheetsList):
  print "Insert row succeeded."
else:
  print "Insert row failed."

That’s it. Run the script to append a new row to the current spreadsheet. By the way, if you make a chart from the spreadsheet data, you can right-click on the chart, select “Publish chart…” from the menu, and get a snippet of HTML to copy/paste that will embed the chart on a web page. It will look like this:

That’s a live image served up by Google, and when the spreadsheet gets new data, the image should update too.

Talking to a Wiimote in Ubuntu 8.10

To add Wiimote support on Ubuntu 8.10, start by running the command “sudo apt-get install wminput wmgui lswm” to install the CWiid library and associated software.

If you’re using a desktop machine, you probably don’t have Bluetooth capability. If you run the program “lswm” and see the message “No Bluetooth interface found” then you need to get a Bluetooth adapter, which is a dongle that uses a USB port to add Bluetooth abilities. I bought the IOGear GBU421 because it seems to be well-supported in Linux and only costs about $20. It’s also so tiny that it’s cute. It looks like this:

IO Gear GBU 421

I told you it was cute. :) Now put your Wiimote in discoverable mode by pressing the 1+2 buttons at the same time and then within 15-20 seconds, run “lswm” again and you’ll get a Bluetooth identifier back:

lswm
Put Wiimotes in discoverable mode now (press 1+2)…
00:17:AB:2A:3C:BD

Congrats, your Linux machine can see the Wiimote! Now run the “wmgui” program to get a very nice user interface that will show you the sensor readings on your Wiimote:

wmgui with a Wiimote

That’s really all there is to it. Once your Ubuntu machine can see the Wiimote, you can do all sorts of tricks with it. You could do head tracking, camera tracking, control MythTV with it, etc. Linux/Ubuntu 8.10 handles the IOGear GBU421 plus a Wiimote really well.

Update: I made a video of using a Wii mote with Ubuntu if you’d like to watch:

css.php