I’ve got a Verizon data uplink thinger for my laptop. This is the second day in a row they’re not able to route my packets. Yesterday I couldn’t access a shared host on WebFaction’s network. Today I can’t access my Slicehost VPS.

mike@110psi:~$ traceroute dev.thefirewoodguys.com
traceroute to dev.thefirewoodguys.com (67.23.12.250), 30 hops max, 60 byte packets
 1  64.sub-66-174-217.myvzw.com (66.174.217.64)  73.717 ms  74.616 ms  75.561 ms
 2  127.sub-66-174-217.myvzw.com (66.174.217.127)  85.524 ms  86.513 ms  86.485 ms
 3  138.sub-66-174-31.myvzw.com (66.174.31.138)  101.457 ms  101.434 ms  101.414 ms
 4  233.sub-66-174-217.myvzw.com (66.174.217.233)  99.385 ms  100.343 ms  75.903 ms
 5  194.sub-66-174-217.myvzw.com (66.174.217.194)  77.883 ms  77.870 ms  77.858 ms
 6  98.sub-66-174-31.myvzw.com (66.174.31.98)  77.847 ms  77.837 ms  72.877 ms
 7  169.sub-66-174-31.myvzw.com (66.174.31.169)  73.820 ms  74.790 ms  82.772 ms
 8  162.sub-66-174-31.myvzw.com (66.174.31.162)  81.781 ms  82.744 ms  83.737 ms
 9  169.sub-66-174-31.myvzw.com (66.174.31.169)  83.729 ms  83.721 ms  83.713 ms
10  162.sub-66-174-31.myvzw.com (66.174.31.162)  75.838 ms  75.791 ms  76.679 ms
11  169.sub-66-174-31.myvzw.com (66.174.31.169)  77.664 ms  78.606 ms  78.576 ms
12  162.sub-66-174-31.myvzw.com (66.174.31.162)  69.817 ms  70.718 ms  77.700 ms
13  169.sub-66-174-31.myvzw.com (66.174.31.169)  78.646 ms  78.617 ms  78.588 ms
14  162.sub-66-174-31.myvzw.com (66.174.31.162)  78.565 ms  79.526 ms  79.503 ms
15  169.sub-66-174-31.myvzw.com (66.174.31.169)  79.487 ms  66.962 ms  66.941 ms
16  162.sub-66-174-31.myvzw.com (66.174.31.162)  67.833 ms  72.801 ms  73.800 ms
17  169.sub-66-174-31.myvzw.com (66.174.31.169)  73.787 ms  79.906 ms  80.854 ms
18  162.sub-66-174-31.myvzw.com (66.174.31.162)  80.840 ms  80.828 ms  81.807 ms
19  169.sub-66-174-31.myvzw.com (66.174.31.169)  81.795 ms  81.786 ms  91.778 ms
20  162.sub-66-174-31.myvzw.com (66.174.31.162)  92.730 ms  93.720 ms  70.790 ms
21  169.sub-66-174-31.myvzw.com (66.174.31.169)  71.735 ms  72.670 ms  77.668 ms
22  162.sub-66-174-31.myvzw.com (66.174.31.162)  75.614 ms  76.604 ms  82.729 ms
23  169.sub-66-174-31.myvzw.com (66.174.31.169)  81.718 ms  82.645 ms  84.634 ms
24  162.sub-66-174-31.myvzw.com (66.174.31.162)  86.585 ms  86.555 ms  86.529 ms
25  169.sub-66-174-31.myvzw.com (66.174.31.169)  86.505 ms  86.481 ms  86.464 ms
26  162.sub-66-174-31.myvzw.com (66.174.31.162)  67.786 ms  68.690 ms  69.682 ms
27  169.sub-66-174-31.myvzw.com (66.174.31.169)  74.649 ms  75.588 ms  75.559 ms
28  162.sub-66-174-31.myvzw.com (66.174.31.162)  73.911 ms  100.955 ms  100.945 ms
29  169.sub-66-174-31.myvzw.com (66.174.31.169)  101.868 ms  104.849 ms  104.840 ms
30  162.sub-66-174-31.myvzw.com (66.174.31.162)  103.834 ms  109.823 ms  110.813 ms

The solution? Disconnect and reconnect. Verizon will give you a new IP, and if you’re lucky, your packets will now (by chance) get routed around their fail.

That’s what it took to get San Francisco to tear down their waterfront freeway.

seattle waterfront freeway

seattle waterfront freeway

Tearing out a freeway without an earthquake – to my knowledge, it’s never been done. It would require an enormous amount of political capital. But there’s a group of Seattle citizens working on just that. They have a lot of logic and the tide of public opinion all pushing their way, and with the existing viaduct coming up for replacement, well – good luck!

This script will make a dump of the Django Book to your local filesystem so you can read it offline. Like say on a flight and you don’t want to pay 10 bucks for an hour of wifi. Even though you’re stoked you finally can, if you need/want to.

This script makes all the css links work so everything’s pretty. Also, Firefox by default won’t render index.html files as directory indexes when working in the ‘file://’ scheme, so this script rewrites internal links so that the index.html is explicit.

#!/bin/sh

# this script downloads a copy of the 2.0 django book, complete with css and
# sets it up so you can read it in-flight

WEB_RT="http://www.djangobook.com/en/2.0"
MIN_CHP=1
MAX_CHP=20

CSS1=http://new-media.djangobook.com/yui/container/assets/container.css
CSS2=http://new-media.djangobook.com/yui-ext/css/resizable.css
CSS3=http://new-media.djangobook.com/yui-ext/css/tabs.css
CSS4=http://new-media.djangobook.com/djangobook.css
CSS5=http://new-media.djangobook.com/yui/grids/grids-min.css
CSS6=http://new-media.djangobook.com/yui/reset/reset-min.css

CSS1_FILE=container.css
CSS2_FILE=resizable.css
CSS3_FILE=tabs.css
CSS4_FILE=djangobook.css
CSS5_FILE=grids-min.css
CSS6_FILE=reset-min.css

DIR_RT=django_book

echo "************ Setting up our dir structure *****************"
mkdir $DIR_RT
mkdir $DIR_RT/css
for i in `seq -f 'chapter%02.0f' $MIN_CHP $MAX_CHP`; do
  mkdir $DIR_RT/$i
done

echo "*********** Downloading all the content *****************"
wget $WEB_RT/ -P $DIR_RT
for i in $CSS1 $CSS2 $CSS3 $CSS4 $CSS5 $CSS6; do
  wget $i -P $DIR_RT/css/
done
for i in `seq -f 'chapter%02.0f' $MIN_CHP $MAX_CHP`; do
  wget $WEB_RT/$i/ -P  $DIR_RT/$i/
done

echo "************** Fixing up the css links ****************"
for i in `seq 1 6`; do
  eval "CSS_F=\"\$CSS${i}_FILE\""
  sed -i "s/href=\".*$CSS_F\"/href=\"css\/$CSS_F\"/" $DIR_RT/index.html
done

for i in `seq -f 'chapter%02.0f' $MIN_CHP $MAX_CHP`; do
  for j in `seq 1 6`; do
    eval "CSS_F=\"\$CSS${j}_FILE\""
    sed -i "s/href=\".*$CSS_F\"/href=\"..\/css\/$CSS_F\"/" $DIR_RT/$i/index.html
  done
done

echo "*************** Fixing up the page links **************"
sed -i "s/href='chapter[0-9]\{2\}\//&index.html/" $DIR_RT/index.html
for i in `seq -f 'chapter%02.0f' $MIN_CHP $MAX_CHP`; do
  sed -i "s/href=\"..\"/href=\"..\/index.html\"/" $DIR_RT/$i/index.html
  sed -i "s/href='..\/chapter[0-9]\{2\}\//&index.html/" $DIR_RT/$i/index.html
done

You ever see those ads back in the day where they’d have a little master combo lock, and someone would fire a handgun right at it? The bullet would ricochet off the lock, sending the lock flapping around all over the place, and when everything settled – there was the lock, still all locked up.

I’m not saying those were faked or anything… but they sure were misleading.

To bust apart your master lock, you’ll need a hammer, a flathead screwdriver, a strong pair of pliers, a good pounding surface, and 15 minutes.

Assuming your lock looks like mine, on the back you’ll find a nice little steel lip. Pound the flathead down under that.

Pound forward so that you can get the flathead under the front dial. It’ll pop right off.

Under the dial there’s a thicker piece of protective steel. Choose a good spot and pound through it using the flathead. Pry up a lip and pull it back with your pliers. The insides of the lock will kinda just dissolve and fall out. Give the lock a tug and bam! Your lock is open.

I just installed ProFont on my Debian machine, using this howto. If you’re looking for a monospace font that maintains readability at extra small sizes, ProFont’s for you. On my 1920×1280 15.4″ LCD display (147 pixels/inch), this allows me to stack up three 80-char wide terminals side by side by side, using ProFont at 7 pixels, while maintaining readability. Screen real estate galore!

I ran across this sweet new form of bike rack yesterday in Palo Alto.

a nice rack

I really, really like the concept – not because it’s that much better from a utility standpoint (although that half-roof is a nice touch). It’s awesome because it takes the bicycle from something pushed to the side and in the way, to something that is the center of attention – on display, worthy of celebration. The mere presence of this rack is one big advertisement: “ride your bike!”

Learn more about these awesome racks at BikeArc.com.

gsynaptics gives you a nice little GUI in gnome to control the options on your synaptics touchpad, like the one my T61p came with. It’s easy to set up on a default debian install, you just need to add a few stanazas to your xorg.conf

Here’s the edits I needed from a default install xorg.conf:

  1. Make a backup of your current xorg.conf
  2. Remove the “Generic Mouse” section. You don’t need it anymore.
  3. Add a section for your touchpad like so:
    Section "InputDevice"
      Identifier  "Synaptics Touchpad"
      Driver      "synaptics"
      Option      "SendCoreEvents"  "true"
      Option      "Protocol"        "auto-dev"
      Option      "Device"          "/dev/psaux"
      Option      "SHMConfig"       "true"
    EndSection
    
  4. And add a line in your “ServerLayout” section referencing your new synaptics section. I didn’t have a ServerLayout section so I had to add one, mine looks like this:
    Section "ServerLayout"
      Identifier  "Default Layout"
      Screen      "Default Screen"
      InputDevice "Generic Keyboard"
      InputDevice "Synaptics Touchpad"
    EndSection
    

Now save everything you’re doing and then restart X11 by hitting cntrl-alt-backspace. If X won’t start back up, you can hit cntrl-alt-f1 and log in at a command prompt, restore your xorg.conf from the backup you made earlier, then run /etc/init.d/gdm restart.

In the event that things just aren’t working, your friend is /var/log/Xorg.0.log. That log file contains the results of your x-server’s parsing of your xorg.conf.

First, for anyone out there that’s pretty quick with vi, I’d recommend you check out the vimperator extension for FF if you haven’t already. It speeds up my sessions quite a bit.

It turns out vimperator sets the browser option browser.startup.page=3 for you every time you fire up your browser. You can see this in your vimperator’s options.js:

// start with saved session
storePreference("browser.startup.page", 3);

This ain’t my cup of tea for a few reasons and I’m not nuts about vimperator overriding what I’ve set in my about:config without asking or telling me. Anyway, you can override vimperator’s override.

In your ~/.vimperatorrc:

set! browser.startup.page=1

I had to remove a few hard drives from a few laptops this morning to do some swapping.  Some of them went really easy, others, not so much.  For quick comparison, here’s the basic stats on the hard drive removal process for each.

Mac PowerBook G4:

  • Tools: #0 & #1 Phillips, 1.5 mm Allen wrench
  • Screws: 34
  • Connectors: 5
  • 4 Keys
  • Battery, ram cover, keyboard, front cover, hard drive casing
  • 90 min
  • High probability of inflicting cosmetic damage to laptop
  • You need a guide, and plenty of organization and patience

removing apple HD 1

removing apple HD 2

HP OmniBook 9000:

  • #1 Phillips
  • 3 Screws
  • 5 minutes

removing hp HD

IBM T61p:

  • #1 Phillips
  • 5 Screws
  • 5 minutes

removing ibm HD

IBM wins as having the most user-friendly design, followed closely by HP. Apple… uh, yeah right.

Apple’s products tend to be very user-friendly as long as you fit nicely into one of their predefined use cases… hard drive replacement apparently isn’t one of their use cases.

I ran across a peculiarity with google mail’s spam checking today. I’m running a bayarea firewood delivery site for a buddy of mine, and it has, among other awesome features, an order form containing a few ‘phone’ strings. When the order form is submitted, an email is sent out to a private email list which is ran using google site’s email app.

I made a few changes to the email script, tested them in the dev environment, pushed the changes to production, then made one final test in the production environment… and holy snikes it doesn’t work! I don’t get an email at my google email list when I submit the order form. What?? It just worked 10 seconds ago on my dev site!

  1. Revert the production code.
  2. Recreate problem in my dev environment.
  3. Track down source of problem.

Long story short, it turns out if I send an email to an email list handled by the google sites email app, and if it contains the string ‘555 555 5555′ then it doesn’t go through. Or at least it gets delayed by 1 hour+. I haven’t seen any of them yet.

Change that ‘555 555 5555′ ever so slightly – say to ‘555 555 5554′ and it goes through in seconds.  Who would a thunk it.

I guess spam often has ‘555 555 5555′ in it? Moral of the story is a) to not get that phone number and b) don’t use common strings like that in your testing. (email@email.com?)  It can introduce unexpected variables.