Archive for February, 2005

How Fast is Your Browser?

February 16th, 2005 by daryl

Want to optimize your browsing experience? Check out this pretty comprehensive set of browser speed tests targeting all of the major browsers and some minor ones on Linux, Mac, and PC. If you’re not into reading the tech specs and methodology, scroll down to the bottom for the conclusions. It turns out that Opera is a pretty darned fast browser. Although the author concludes that Mozilla and Firefox are optimized for Linux, it seems to me that Opera wins almost across the board, especially on Windows. Of course, Firefox is free, easily extended, and simple out of the box, so it’s still my browser of choice.

Incidentally, Firefox netted 25 million downloads in 100 days. About 110 days ago, when we on the Spread Firefox crew were trying to project a reasonable download count for 100 days, we landed on 10 million. Similarly, the NY Times campaign wound up raising something like six times what some of us thought we could reasonably expect. It’s amazing how many extra miles the Firefox community keeps going.

Word Press and Del.icio.us; Word Press and Amazon

February 14th, 2005 by daryl

In a post this morning, I went over briefly my inclination to write an audioscrobbler plugin for Word Press. Other things I needed to aggregate for the project I was doing that for included del.icio.us feeds and amazon book lists. Flickr already provides a javascript snippet to display images, and I’m not going to take the time to rewrite that one for now. But I did decide to go ahead and write my own plugins to display del.icio.us and amazon information.

Why not use something that’s already out there, including my own amazon plugin? Well, the existing plugins aren’t as flexible as what I wanted to do. For example, you have to hack your index.php file in order to add the amazon wishlist output to your page unless you want it just automatically appended to your categories listing. Plus the amazon plugin retrieves wishlist info only, and you might want to display books you’re currently reading without risking adding them to your wishlist and getting duplicate copies. Additionally, I’m really digging the smarty engine that Word Press 1.5 uses, and in order to add stuff to templates, it makes pretty good sense to write the plugins as smarty plugins. The del.icio.us plugin doesn’t really require much flexibility and is essentially a duplication of the audioscrobbler plugin, though I’ve added a parameter that allows you easily to limit the number of links displayed. The template code is as follows:



<li>Del.icio.us
<ul>
{delicious feed=”http://del.icio.us/rss/tag/r2″ cache_dir=”/var/www/html/wpmu/wp-inst/cache/” records=”10″}
</ul>
</li>

You pass a feed URL, a writable directory to cache the feed in so we don’t tax the del.icio.us servers, and the maximum number of records to display. Part of the beauty of this plugin (or actually of the API that supports it) is that you can include the smarty tags several times in your template to display different feeds. And because things like the records limit are passed on a per-instance basis, there’s no global or function-scoped setting forcing you to always have X number of links, so you can have 10 blog links and 5 design links and 3 links of some other type, for example. The actual plugin code looks very much like the audioscrobbler code:

[php]
define(”CACHE_EXPIRY”, 60*10); //seconds to cache data for
define(”CACHE_DIR”, “/var/www/html/wpmu/wp-inst/cache/”);//where to cache

//Make this a smarty function by using the API’s naming convention.
function smarty_function_delicious($params, &$this){
//Bust params array into key=value pairs.
extract($params);

if($records==” || !$records || intval($records)==0){
$records=10;
}
//If no username param passed, we can’t very well fetch a feed.
if($feed==” || !$feed){
print “Could not load del.icio.us plugin.”;
}
//Else call the workhorse function and print the resulting output.
else{
$output=show_delicious($feed,$records);
print $output;
}
}

//Function to handle caching/fetching of URL.
function getDeliciousXmlUrl($url) {
$goodToUpdate = true;
$hash = md5($url);
$filename = CACHE_DIR.$hash;

//If we’ve already cached this feed…
if ( file_exists($filename) ) {
$time = filectime($filename);
//Check the time it was last cached based on cache file timestamp.
if ( $time > (time() - CACHE_EXPIRY) ) {
//it was last written less than CACHE_EXPIRY seconds ago
$goodToUpdate = false;
}
//Set $xmlFile to contents of cached file in case we need it.
$xmlFile = file_get_contents($filename);
}

//If we’re not cached or the cache has expired…
if ( $goodToUpdate ) {
//Get the url content. Your php.ini has to allow remote URLs to be opened as files for this to work.
$xmlString = file_get_contents($url);
if(!$xmlString){
//something broke, sliently move on
}
else{
//Write the contents to the cache filename determined above.
$fp=fopen($filename,’w');
fwrite($fp,$xmlString);
fclose($fp);

//Set $xmlFile to the newer data.
$xmlFile = $xmlString;
}

}
return $xmlFile;
}

//This does the real work of the plugin.
function show_delicious($url,$records) {
require_once “XML/Unserializer.php”;

//Get the XML from the passed URL.
$xml=getDeliciousXmlUrl($url);

//PEAR class that does the work invoked here.
$rss =& new XML_Unserializer();
$result= $rss->unserialize($xml,false); //False makes it treat the param as a string rather than as a file.
$feed=$rss->getUnserializedData();

//print “

$feed,1) . "

“;

$output=”";
//If no items in feed, let user know.
if(sizeof($feed["item"]) == 0){
$output .= “n

  • no recent links (” . sizeof($feed["channel"]["item"]) . “)
  • n”;
    }
    //Else iterate over the items and print out title/url.
    else{
    $del_count=1;
    foreach($feed["item"] as $item){
    if($del_count < = $records){
    $output .= "n

  • ” . $item["title"]. “n”;
    }
    else{
    break;
    }
    $del_count++;
    }
    }

    return $output;
    }
    [/php]

    The amazon plugin is a little more involved. Initially, it was very much like the other two plugins I’ve mentioned here, with the output hard-coded, but I wanted to make this one more flexible. For example, I wanted a user to be able to dictate what data fields were displayed and with what CSS selectors attached to them without having to define and hard-code a bunch of selectors and flags to determine what to code. In other words, I didn’t want users to have to type a tag like the following and still be limited as far as layout by some hard-coded values:


    {amazon dev_token="XXXXXXXXXXXX" associate_id="YYYYYYYY" isbn="4770029055,1400043662" cache_dir="/var/www/html/wpmu/wp-inst/cache/" image_class="small_image" show_small_image="1" title_class="amazon_title" show_title="1" price_class="price_class" show_price="1" release_date_class="rd_class" show_release_date="1"}

    Instead, I worked it out so that users can add something like the following to the template:


    <!--Amazon-->
    <li>Amazon
    <ul>
    {amazon dev_token="D3TF1MNM1YQKGD" associate_id="rationalisofeast" isbn="4770029055,1400043662" cache_dir="/var/www/html/wpmu/wp-inst/cache/"}
    {foreach from=$amazon_list key=key item=hits}
    <li><a class="amazon_link" href="{$hits.url}"><img class="amazon_image" src="{$hits.small_image}"><br/><span class="amazon_title">{$hits.title}</span><br/></a><b>Price: </b>{$hits.list_price}</li>
    {/foreach}
    </ul>
    </li>
    <!--End Amazon-->

    In other words, the design and determining what elements to display can be controlled completely through the template so that designers don’t have to go poking through PHP code to try to figure out how to change a style attribute on an image or a title. The key is knowing what parameters are valid to use within the template, and in this case, they’re as follows:

    • isbn
    • title
    • url
    • authors
    • catalog
    • small_image
    • medium_image
    • large_image
    • availability
    • list_price
    • sale_price
    • used_price
    • release_date

    Now for a brief description of how the template parsing works (or, more accurately, what you need to know in order to incorporate these attributes into your template). First, you have to include the line:


    {amazon dev_token="XXXXXXXXXXXXX" associate_id="YYYYYYYY" isbn="4770029055,1400043662" cache_dir="/var/www/html/wpmu/wp-inst/cache/"}

    The dev_token parameter is something you get from amazon, as is the associate_id (which allows you to get monetary credit for books purchased through the link this generates). The cache_dir, as in the other plugins, should represent a Web-server-writable path on your system and is used to help keep load down on the servers we’re connecting to in order to get the data. The isbn parameter contains a comma-separated list of the ISBNs for the books you want to display. Ideally, this can one day be dynamic or based on info pulled from a database and populated through an admin tool, but for now, this does the trick. This line of code causes the data to be grabbed from amazon and stored in the smarty object. Which is where the foreach in the template comes in. The forech block tells smarty to iterate over the variable $amazon_list (which the line above created and populated with an array for each book retrieved) and to store the array in a local variable named “hits.” The values of the array for each iteration can be accessed using dot-syntax, where the piece after the dot corresponds to one of the keys defined in the list above. In other words, we’re iterating over the array returned by the initial line and, for each array within that array, plugging its values in by name where listed within brackets here using the dot-syntax. This allows designers to wrap whatever layout and design tags they wish to around the data and keeps design-retarded coders like me from making stupid design decisions that are hard-coded into the smarty plugin. Within the foreach loop, to get the title for a given book, we’d use {$hits.title}. To get the url, we’d use {$hits.url}. And so on. The code for the plugin itself is as follows:

    [php]
    define(”CACHE_EXPIRY”, 60*10); //seconds to cache data for
    define(”CACHE_DIR”, “/var/www/html/wpmu/wp-inst/cache/”);//where to cache
    define(”BASE_AMAZON_URL”,’http://xml.amazon.com/onca/xml3?page=1&type=lite&locale=us&f=xml’);
    //http://xml.amazon.com/onca/xml3?locale=us&t=rationalistsofeas&dev-t=D3TF1MNM1YQKGD&AsinSearch=4770029055&mode=books&sort=+titlerank&offer=All&type=lite&page=1&f=xml

    //Make this a smarty function by using the API’s naming convention.
    function smarty_function_amazon($params, &$this){
    //Bust params array into key=value pairs.

    extract($params);

    if($dev_token==” || $isbn==”){
    print “Must pass dev_token and isbn as params”;
    exit;
    }
    if($records==” || !$records || intval($records)==0){
    $records=5;
    }
    $feed=BASE_AMAZON_URL . “&dev-t=” . $dev_token . “&t=” . $associate_id . “&AsinSearch=” . $isbn;
    // print $feed; exit;
    $output=show_amazon($this,$feed,$records,$associate_id);
    print $output;
    }

    //Function to handle caching/fetching of URL.
    function getAmazonXmlUrl($url) {
    $goodToUpdate = true;
    $hash = md5($url);
    $filename = CACHE_DIR.$hash;

    //If we’ve already cached this feed…
    if ( file_exists($filename) ) {
    $time = filectime($filename);
    //Check the time it was last cached based on cache file timestamp.
    if ( $time > (time() - CACHE_EXPIRY) ) {
    //it was last written less than CACHE_EXPIRY seconds ago
    $goodToUpdate = false;
    }
    //Set $xmlFile to contents of cached file in case we need it.
    $xmlFile = file_get_contents($filename);
    }

    //If we’re not cached or the cache has expired…
    if ( $goodToUpdate ) {
    //Get the url content. Your php.ini has to allow remote URLs to be opened as files for this to work.
    $xmlString = file_get_contents($url);
    if(!$xmlString){
    //something broke, sliently move on
    }
    else{
    //Write the contents to the cache filename determined above.
    $fp=fopen($filename,’w');
    fwrite($fp,$xmlString);
    fclose($fp);

    //Set $xmlFile to the newer data.
    $xmlFile = $xmlString;
    }

    }
    return $xmlFile;
    }

    //This does the real work of the plugin.
    function show_amazon(&$smarty,$url,$records,$associate_id) {
    require_once “XML/Unserializer.php”;

    //Get the XML from the passed URL.
    $xml=getAmazonXmlUrl($url);

    //PEAR class that does the work invoked here.
    $rss =& new XML_Unserializer();
    $result= $rss->unserialize($xml,false); //False makes it treat the param as a string rather than as a file.
    $feed=$rss->getUnserializedData();

    //print “

    " . print_r($feed,1) . "

    “;

    $output=”";
    //If no items in feed, let user know.
    if(sizeof($feed["Details"]) == 0){
    $output .= “n

  • no products found
  • n”;
    }
    //Else iterate over the items and print out title/url.
    else{
    $am_count=1;
    $items=array();
    foreach($feed["Details"] as $item){
    if($am_count < = $records){
    array_push($items,array(
    "isbn" => $item["Asin"],
    “title” => $item["ProductName"],
    “url” => “http://www.amazon.com/exec/obidos/ISBN%3D” . $item["Asin"] . “/” . $associate_id,
    “authors” => join(”, “,$item["Authors"]),
    “catalog” => $item["Catalog"],
    “small_image” => $item["ImageUrlSmall"],
    “medium_image” => $item["ImageUrlMedium"],
    “large_image” => $item["ImageUrlLarge"],
    “availability” => $item["Availability"],
    “list_price” => $item["ListPrice"],
    “sale_price” => $item["OurPrice"],
    “used_price” => $item["UsedPrice"],
    “release_date” => $item["ReleaseDate"],
    ));
    //$output .= “n


  • ” . $item["ProductName"]. “
  • n”;
    }
    else{
    break;
    }
    $am_count++;
    }
    $smarty->assign(”amazon_list”,$items);
    }

    return $output;
    }
    [/php]

    Word Press and Audioscrobbler

    February 14th, 2005 by daryl

    My new company’s Web site will feature blogs by those of us who have interesting things to say about our industry. In order to make the blogs richer and more personalized, the guy coordinating them wants each blog to have its own del.icio.us feeds, Audioscrobbler feeds, Flickr feeds, etc. Initially, I had settled on using Movable Type because, in addition to providing multiple blogs for multiple users, there were already plugins to do all of these things, and there was a plugin to aggregate all posts into one blog, which blog could be used as the home page. And since each user had his own template, the feeds could all be distinct without the need to hack any code.

    Another guy working on the Web site started pushing Word Press really hard, and with good reason. It’s a great blogging system and is in fact what I use for my blog. Furthermore, it’s written using PHP rather than perl (MT uses perl) and so is much more pleasant for me to maintain. But while it boasts multiple-blogger functionality, there’s no way short of installing a new version of the software for each blogger to let bloggers have different templates. Or I didn’t think there was, at any rate. It turns out that there’s a beta version of a multi-user Word Press. Essentially, it’s a set of hacks that let the application keep redundant data across blogs in some main tables, duplicating tables only for blog-specific info (such as posts). It’s pretty ugly, and one actually probably would have about as easy a time, for smaller blog setups, just installing the software multiple times. Matt Mullenweg, the creator of Word Press, has said as much. Word Press MU is still in beta, after all.

    I took a stab at writing a plugin that would aggregate posts from all blogs into a single blog post listing, and it was a bit of a pain precisely because blogs are stored in different tables rather than in the same table with different ids. I got the base functionality working, but it actually becomes very complex to make it work with any granularity at all. For example, to display a permalink and have it link to the right blog (rather than simply the current one, for which the permalink might not be valid), you have to do all sorts of wizardry. And I didn’t even try to screw with displaying categories on a per-blog basis. I got things to a point at which they’re usable for my purposes, though, and decided to move on to integrating plugins to handle del.icio.us, audioscrobbler, and flickr. Luckily, plugins for these bits of functionality already exist.

    Except that the widely-publicized one for audioscrobbler has been removed. So my fun late last week and this morning included rolling my own. Actually, I found another one, but it assumes that you have PHP5, which I don’t (and don’t want to upgrade right now). So I took pieces of that one and modified it. Further, I turned it into a smarty template plugin that makes it dead simple to use in the MU version of Word Press, which uses smarty to handle templating and template caching. So in order to add an audioscrobbler feed to a template now, I have to add only the following to the template:


    <!--Audioscrobbler-->
    <li>Audioscrobbler
    <ul>
    {audioscrobbler username="factoryjoe" cache_dir="/var/www/html/wpmu/wp-inst/cache/"}
    </ul>
    </li>
    <!--End Audioscrobbler-->

    And actually, only the middle line is essential; the other stuff’s there because that’s what makes the output appear correctly within my template. The username parameter of course represents the audioscrobbler username, and the cache_dir parameter tells the plugin where to cache feed information. Basically, it’s rude and in most cases in violation of a service agreement to fetch a feed for every page load, so my code caches the feed and refreshes the local cache periodically.

    The primary thing the original plugin needed PHP5 for was XML parsing. PHP5 comes with lots of built-in tools for doing that, while PHP4 tends to rely on hand-rolled classes. There are some PEAR classes that’re good for parsing feeds, so I modified the relevant code to use them instead of PHP5’s tools. I also added code to register the code as a smarty template function. Here’s the code:

    [php]
    define(”CACHE_EXPIRY”, 60*10); //seconds to cache data for
    define(”CACHE_DIR”, “/var/www/html/wpmu/wp-inst/cache/”);//where to cache; a default that’s overridden in the template parameters
    define(”BASE_AS_URL”,”http://ws.audioscrobbler.com/rdf/history/”); //Where to look for the feed (will append username)

    //Make this a smarty function by using the API’s naming convention.
    function smarty_function_audioscrobbler($params, &$this){
    //Bust params array into key=value pairs.
    extract($params);

    //If no username param passed, we can’t very well fetch a feed.
    if($username==” || !$username){
    print “Could not load Audioscrobbler plugin.”;
    }
    //Else call the workhorse function and print the resulting output.
    else{
    $output=show_audioscrobbler(BASE_AS_URL . $username);
    print $output;
    }
    }

    //Function to handle caching/fetching of URL.
    function getXmlUrl($url) {
    $goodToUpdate = true;
    $hash = md5($url);
    $filename = CACHE_DIR.$hash;

    //If we’ve already cached this feed…
    if ( file_exists($filename) ) {
    $time = filectime($filename);
    //Check the time it was last cached based on cache file timestamp.
    if ( $time > (time() - CACHE_EXPIRY) ) {
    //it was last written less than CACHE_EXPIRY seconds ago
    $goodToUpdate = false;
    }
    //Set $xmlFile to contents of cached file in case we need it.
    $xmlFile = file_get_contents($filename);
    }

    //If we’re not cached or the cache has expired…
    if ( $goodToUpdate ) {
    //Get the url content. Your php.ini has to allow remote URLs to be opened as files for this to work.
    $xmlString = file_get_contents($url);
    if(!$xmlString){
    //something broke, sliently move on
    }
    else{
    //Write the contents to the cache filename determined above.
    $fp=fopen($filename,’w');
    fwrite($fp,$xmlString);
    fclose($fp);

    //Set $xmlFile to the newer data.
    $xmlFile = $xmlString;
    }

    }
    return $xmlFile;
    }

    //This does the real work of the plugin.
    function show_audioscrobbler($url) {
    require_once “XML/Unserializer.php”;

    //Get the XML from the passed URL.
    $xml=getXmlUrl($url);

    //PEAR class that does the work invoked here.
    $rss =& new XML_Unserializer();
    $result= $rss->unserialize($xml,false); //False makes it treat the param as a string rather than as a file.
    $feed=$rss->getUnserializedData();

    $output=”";
    //If no items in feed, let user know.
    if(sizeof($feed["item"]) == 0){
    $output .= “n

  • no recent tracks (” . sizeof($feed["channel"]["item"]) . “)
  • n”;
    }
    //Else iterate over the items and print out title/url.
    else{
    foreach($feed["item"] as $item){
    $output .= “n

  • ” . $item["description"]. “
  • n”;
    }
    }

    return $output;
    }

    [/php]

    I just added this code to a file called function.audioscrobbler.php in the smarty-plugins directory, added the template code listed above to my template, and — voila — I had an audioscrobbler feed in my sidebar. Pretty nifty.

    I Won’t Rape You

    February 10th, 2005 by daryl

    I always feel guilty when walking alone in the dark and approaching a woman or women. I’ve had this guilt since college, when I learned about “Take Back the Night” marches wherein women united to march fearlessly in large crowds around campus, taking a stand about the injustice of women’s having to be afraid to walk alone in the dark lest they be raped. I can sort of identify with the fear; as strapping or at least solid and not-fuck-with-able as I probably appear all hunkered down loping along in the dark, I often tense up when I see another man or men walking toward (or, possibly worse, behind) me. I instinctively hunker down a little more and unconsciously make an effort to look even more un-fuck-with-able, broadening my already broad shoulders, leaning into my gait a little more as if to give the appearance of momentum and of aggression, generally trying to look a little more badass, though I’m really pretty much a wimp.

    So, burly as I am, and with less physically at stake than what I suspect most women feel they have at stake, I can sure understand how frightening it might be for a woman walking around at night to see even harmless little old me walking toward her. And every time it happens, I feel a pang of guilt and wish there was something I could do to signify that I’ve got no ill intentions.

    You can’t exactly walk around saying “I’m not going to rape you” or holding a sign to that effect, because to do so would invite suspicion that for some women might not already be there (perhaps I’m wrong, in other words, to assume that women share with me – but to a greater degree – this fear of other passers by). Or I’d just look crazy, which, again, wouldn’t be exactly reassuring under the circumstances. Maybe I could always juggle while I walk. Or wear a clown nose (ok, bad associations there, and the crazy suspicion). Or affect feminine mannerisms. Or always move around at night in a wheelchair or otherwise lurch around as if crippled and therefore unlikely to indulge in rape. Or always walk with a woman (or will they think I’ve kidnapped her?). Or maybe just not walk anywhere in the dark.

    There doesn’t seem to be a really workable solution. In any case, if you happen to see me walking around at night, I promise I’m not going to rape you or beat you or ogle you or even just steal your purse. I hope you’ll extend me the same courtesy.

    The Viet Cong Taking over Silicon Valley

    February 10th, 2005 by daryl

    So all week long out in Silicon Valley, all I hear is VC this, VC that. “I had lunch with some VCs today and they really liked our business model.” “Forbes issued a list of the top 100 VCs, and X was in the top 25.” Who would have thought that the Viet Cong would descend upon Silicon Valley and, further, that they would exert the sort of influence they apparently do?

    Shoeboxes

    February 9th, 2005 by daryl

    One of the exhibits at the SF Museum of Modern Art was a room whose walls had about 40 roughly shoebox-sized recesses in them. Each recess contained one or two women’s shoes, and each had animal skin (or maybe it was gut lining) stretched drum-tight over it and stitched to the wall. The skins were yellow-brown and gauzily translucent, so that you could see the shoes inside, but not terribly well. The boxes were of varying widths but roughly the same height, and they were at sternum level for me. Most of them had two shoes vertically oriented, toe-down. Some had just one shoe, and some had one shoe oriented vertically and the other leaning against it at an angle. The blurb about the exhibit said that its artist (whose name I forget) was reacting to a situation in Colombia that caused women to be killed. Each pair of shoes represented a particular woman who had been killed. In one corner of the room, a number of boxes composed of the skin/gut were stacked up sort of haphazardly.

    I found the exhibit compelling (though apparently not enough so that I took time to remember precisely what it was a reaction to), and just this morning, it made me think of an exhibit that came to Chapel Hill when I was a student there. This one too filled a room. It was a set of plaster masks formed from the faces of AIDS victims. Each mask had a little blurb about the victim beside it. Besides the variety of the masks (anybody can get AIDS), what affected me the most about the exhibit was what the experience of its composition must have been like. Consider that people get the heebie jeebies about AIDS, going so far (maybe not so much anymore, but this was always a point that was gone over in my health classes when I was younger) as to try not to use a toilet after somebody with AIDS. AIDS always seemed to me, educated as I was about it, rather like leprosy: You just didn’t really want to get near somebody with AIDS if you could help it lest the virus ignore the nice safe assurances that it’s communicable only through the exchange of bodily fluids and leap from the carrier to you. And so here this artist has gotten really sort of up close and personal with each of the victims represented in the exhibit. Moreover, I imagined at the time that having your face plastered to make a mold was probably sort of therapeutic, like applying a hot towel after a shave but better. So the process of the art for this exhibit resulted in a three-pronged work of documentation, therapy, and art that I found very satisfying and sort of touching.

    California, Day Two

    February 5th, 2005 by daryl

    Today, I ventured out to San Francisco. After meeting with Bart for breakfast and getting some tips from him about how to get to the Golden Gate Bridge and some of the other things I might want to hit, I took off in the pickup truck I rented (it was the cheapest thing available, and it was that or maybe an Expedition, which is so expensive that filling up the gas tank for that requires like a co-signer, a passport, and notarization of various imposing documents in triplicate). I stopped by a bookstore at the very cool mall in Palo Alto to get a map of San Francisco (would you believe ten smackaroonies for a map that doesn’t even fully obscure your windshield when you open it up all the way?). The map turned out to be worth every penny.

    From the mall, I struck out heading north on Highway 101, which apparently runs from Seattle down to Mexico, with the bridge as my northernmost and intended first stop. Lucky for me, 101 takes you straight through to the bridge, though there’s a little dicey city street negotiation on the way. All in all, it was very simple, though, the only real hitch that I began to get really low on gas in the middle of SF, and there wasn’t exactly an abundance of gas stations (if I had rented the Expedition, I’d've had to stop to fill up every 100 yards, which with all the notarization and draining of blood from turnips and rending of garments and removal of arms and legs would have become time consuming and logistically/physically problematic in a hurry). But I found one at last and continued on my journey. I knew I was getting close at one point, but I forget whether I had caught a glimpse of the bridge or just saw a sign saying the bridge was close or just heard the humming chorus of bridge angels above the traffic noise, but whatever the case, I tried calling both Mleeka and my parents to let them know that I was almost there.

    Which sounds just absurdly dumb, I know, but for anybody reading this who doesn’t know me, let me explain that I have a bit of a bridge fetish, with the Golden Gate bridge as the primary object of that fetish. It’s actually more a “feats of engineering” fetish with bridges as a special interest and this bridge in particular as the sort of Platonic ideal of all things bridge. Illustrating the breadth of my infatuation with the bridge are the following points:

    • One of the cool “smart” TV stations a few years ago played a documentary about the bridge over and over again, and I watched it over and over again, memorizing facts and being generally sort of obsessive about the whole thing.
    • A few years ago, I bought a sort of artistic rendering of a schematic of the bridge and its terrain and measurements that hangs on my living room wall across from the second piece in the series, of the Brooklyn Bridge, which I bought shortly after making the first purchase.
    • My parents one Christmas managed to lay their hands on a canceled bond that was used to raise funds for building the bridge. I’ve been meaning for years to get the thing framed (it’s beautiful and looks like big old money in all its green-inked ornament), and Mleeka finally found a frame last week that would allow you to see both sides of the bond, so it’ll be hanging on the wall soon.
    • Umm, I called both my wife and my parents as I approached the bridge to tell them that I was about to cross it, and it felt almost as if I was calling to say I’d just won the Tour de France or something.

    So yeah, it’s sort of a fetish, and boy was it indulged today. The bridge is freaking huge. Its whole length from beginning to end is more than 8,000 feet, and the actual span over water is most of a mile. As you’re nearing the end of the bridge, trying hard not to veer into other lanes because you’re looking up at the amazing towers and cables, you see a sign telling you that the curb-side lane goes to Vista Point. I opted for that lane, which took me to parking and a vista (surprise) overlooking the bay and giving a nice length-wise view of the bridge. I hung out there for a few minutes getting the view from afar, but then I took off for the bridge itself, which conveniently has nice big railed-in sidewalks designed to accommodate tourists, bikers, etc. I walked from the north end of the bridge to one of the towers, stopping frequently to look up at the cables and pausing for a few minutes at the tower to sort of take in the grandeur of this astonishing structure. The rivets holding the thing together have heads the size of golf balls, and from the tower (but at road level, of course), it takes eleven seconds for falling spit to become so small that you can’t tell whether it’s hit the water or is just too distant to see. The huge cables for the bridge are composed of a sort of honeycomb of bundles of small cables. If I remember correctly, each bundle has something like 81 maybe quarter-inch cables in it, and then the bundles are bunched together into a huge cable three feet across that is then spiraled around by a single strand of the small cable. In total, there are 80,000 miles of cable in the bridge. The vertical cables are substantially smaller, about the size of my fairly beefy upper forearm and impossible to even come close to getting one hand around unless you’re Andre the Giant, and each vertical strand that seems to be one strand from afar is actually four of them arranged in a square with six or eight inches between the corner cables. When you’re close to the end of the bridge, you can grab one of these vertical cables (also composed of smaller cables twisted together) and yank it back and forth really hard, and though it doesn’t really move, you can tell that it’s sort of vibrating just the tiniest bit all the way to the top. If you lean against the outside rail, it hums and vibrates with the rush of traffic, and if you cock your head back to look up to the top of the towers, you feel like you’re going to pitch over backward into the bay. From the bridge, you can see Alcatraz sitting right there in the bay, and beyond that, the Bay Bridge, which I didn’t go on and which isn’t quite as impressive as the Golden Gate bridge, but which really is a pretty nice bridge in its own right; and while I was there, I started a quick informal count of the sailboats on my side of the bridge and stopped at 70 with plenty more to go.

    As I was out there, I couldn’t help thinking back to an ambition I had once to write something about the bridge. I know Hart Crane’s already done it, or something very similar. Mine was going to be an elaborately symbolic meta-poetics piece probably positioning the bridge as a sort of Eolian harp (see the bit on humming above) but also as a built structure, as something spanning two points poetic-line-like. I think there was also going to be something about the way the cables were run, going back and forth, back and forth across the bay on a sort of suspended pulley apparatus once the first line was ferried across and how this represented the back and forth of a poem across the page. It would have been horrible and forced, and I’m glad I never managed to write it.

    But there was something inspiring about being there, about seeing this marvel of engineering. I staggered around looking upward, shielding my eyes from the sun and talking aloud to myself, thinking hard about the ingenuity it took to design and build the thing, the ambition and the power of the human drive that makes things like this possible. I thought up all sorts of flowery phrases I might use in writing about the experience, and of course they faded as the day pressed on, and I’m glad of it, because then my account would have been imbued more with artifice than with truth and appreciation and the sort of boyish wonder that makes it impossible for you not to spit off the bridge even while feeling very reverent about being there (try something like this at a funeral). I could have stayed there all day.

    But I had other things to do. It was close to 2:00 when I wrapped up and crossed the bridge again, and as I was meeting Bart for dinner at around 8:00, it was about time to grab some lunch. He had recommended that I hit pier 39 on the waterfront, so I got out my trusty map and wound my way over there. I was too dumb and cheap to find long-term parking, and the only meters I could find nearby were half-hour meters, so I parked a couple of blocks away and hauled ass up to the wharf, where there were booths selling tickets for Alcatraz tours and ferry rides. There was a guy sitting on the ground playing some small bongo drums with a coffee can in front of him to collect donations, and I saw little old men walking around together holding hands. There was a guy with sort of a rickshaw (not really a rickshaw but sort of a bicycle rickshaw), and there were lots of tourists with windblown hair. Bart had recommended getting some crab, so I went to a place on pier 39 called “Crab House” that was really very expensive. But I was in a hurry and didn’t want to go hunting around for another place, so I sat down and ordered a salad that I believe they called a Foggy Wharf Salad. It’s basically mixed greens with tomato chunks, dressing, and one of several meats. I got the crab, and it turned out to be a very good salad, whatever their dressing was (something with ginger in it, I think the guy said) really giving it some zing, though I don’t know that it was a $15 salad, even if at $15 it was one of the least expensive things on the menu. It was a weird sort of restaurant, with sort of hokey plastic crab decorations but a wait staff dressed very sharply and a touch on the snobby side. I plowed through the salad in about five minutes and virtually ran back to the truck to find the meter just expired. I had to pee, so I put in a couple more dimes and walked a couple of blocks over to make use of the Sheraton’s fine facilities. On the way (this is the only reason I mention the bathroom trip, my body functions probably not generally of great interest to anybody reading this account), I passed two gentlemen in Hell’s Angel-like garb, but one of them had a necktie on under his leather vest and jacket, and it was a really incongruous, memorable image.

    Next stop, the San Francisco Museum of Modern Art, which took a while to get to because I kept taking wrong turns and going around the wrong block and missing the turn into a parking lot and so on. I finally got there at about 3:30 and didn’t leave until closing time at 5:45. It’s an amazing museum with lots of really cool pieces, and I wish I could remember the names of some of my favorites. I really like a lot of the abstract stuff, and I find paintings that have paint just gobbed on thickly very appealing. There was one such painting in grays and black with paint several inches thick in places that looked more like a wall sculpture than a painting, and its explanatory blurb said that there were some 500 pounds of paint on the canvas. I saw pieces by Mondrian, Picasso, Rothko (underwhelming), Matisse, O’Keeffe, Warhol, Kahlo, Pollock, and other famous names that elude me for now, but there were also lots of really cool things by people I had never heard of (which doesn’t mean much because I don’t know much about art). One exhibit featured design as art and included a motorcycle, various chairs, and a Macintosh titanium G4 as pieces. Another was a tall (I’m talking 30 or 40 feet tall) room with the sound of running water and a sort of clumsy paint-by-numberish forest scene on most of the wall space (with the unpainted edges actually trailing off into the outlines and numbers of a paint-by-numbers design). Then there’s a window high up with prison bars and blue (sky) visible outside. The water turns out to be coming from a big sink attached to one of the walls. There’s also a box of rat poison under the sink and stacks of bundled newspapers lying around. It turns out that each separate element of the combined piece is listed as a separate piece, but they all coalesce to form a jarring and humorous exhibit. You walk into the room and find yourself looking up the high walls and hearing the water and then chuckle as you see that the water’s coming not from a babbling brook as the walls might suggest but from an almost industrial sink. Then there’s the prison and the idea of being trapped in this forest and this fractured reality. I found this one to be very satisfying and memorable. At one point, as I was walking away from some cubist pieces, I found myself wondering if there’d be anything by Duchamp, and no sooner did I turn around than I nearly knocked “Fountain” off its pedestal. Very cool. There were so many things I wanted to remember and document from this experience. It was just so visually and mentally stimulating to see this wide array of art, much of which defied decoding in any usual comfortably structured way. It’s really hard not to try to attach meaning to art and not to try to map abstract pieces to processable reality, but once you realize that these aren’t necessarily the objectives, it can be very pleasurable just to look at pieces of art and enjoy their visual offering.

    It was starting to get dusky when I left the museum, and I wanted to start back for Palo Alto before it got too dark. I wound my way back to 101 by a different route than I had taken in (my location now being substantially different), passing through some slummy areas complete with limb-deficient men on crutches and in wheelchairs hobbling/wheeling themselves out from under overpasses through stopped traffic looking for donations. This sort of ruined for me a feeling I had begun to have during the day that San Francisco was a sort of perfect city, easily navigable with lots of neat shops and attractions and some really cool architecture and as far as I had seen no bad areas or crazy people lying possibly dead and covered with newspapers in the middle of the sidewalk. I’m floating on this cloud of satisfaction and riding off into the sunset when here comes this toothless guy with one of the legs of his dirty jeans rolled up into a hollow nub having a hard time managing both his crutches and his donation cup. And after him a guy missing an arm. And after him a guy in a bathrobe wheeling his chair along with his one good leg and looking really haggard and probably sincerely in serious need. I can’t really doubt that these guys have a legitimate need, but it puts me now in mind of the gypsies in The Hunchback of Notre Dame (which by the way Disney royally fucked up and you really ought to read the actual macabre book, which is good and ultimately disturbing in an “A Rose for Emily” sort of way that, well, Disney won’t be going there any time soon) who have like prostheses and other elaborate ways of making people think they’re cripples when in fact they’re just making a living by playing on people’s sympathies. (And then there’s also an X Files episode in which there’s this little scabby legless Indian guy who scoots around on one of those boards you slide around on under a car while doing repairs and who crawls up into people’s asses to sort of use their bodies for a while until they’re pretty much drained and then I guess he’s back on his squeaky little auto-mechanic apparatus again.) But as I pass these guys, feeling both guilty and a little angry (for various reasons), it occurs to me that of course every city, and especially major cities, have these areas. San Francisco, with its hillsides lined domino-like with white houses, with its sort of quaint wharf area and its trolley cars and electric buses and manageable streets and awe-inspiring bridges, with its many beautiful cultures, its thought-provoking art museum, with all the great things that San Francisco has and is, it is of course still a big city, and, like my own provincial little Knoxville, it can’t all be sunshine and flowers. Even Knoxville has a homeless shelter and people shivering under overpasses.

    It was a great day, maybe one of the most satisfying I’ve had in years because of the bombardment of ideas and spectacles. One thing I had hoped to do but opted not to in the end was to run by the City Lights bookstore, which Ferlinghetti founded and can apparently still be found at sometimes with his red pickup parked outside. I stopped by Borders in Palo Alto tonight and read a little bit of Ferlinghetti to make up for the loss. I’m considering trying a run down to Monterrey for a little Cannery Row pilgrimage before I leave on Wednesday, but I’m not sure it’ll happen. Whether that pans out or not, today’s activities have made the whole trip very much worth my while, and I can’t articulate adequately how glad I am that I managed to put aside my worries and venture out.

    California, Day One

    February 5th, 2005 by daryl

    So far, I haven’t suffered derision by hookers or whinos. I got into town at a little after 6:00 p.m. PST on Thursday and moped around trying to figure out how the hell I was going to get to Mountain View. I finally decided on a door to door shuttle because a taxi ride was going to be a hundred bucks and dandruffy and intimidating. I rode with a nice group of people with whom I shared a few chuckles and got out for $40 total, including a generous tip to the driver, who was very helpful. The only downside was that it took an hour and a half because I was the last passenger, and it was dark, so I couldn’t really see much of anything. My hotel’s pretty nice, though I move out today and into another one in Palo Alto, no longer on the Mozilla Foundation’s dime.

    I’m here for a summit on the Spread Firefox initiative, which I helped start up back in the Fall and which has been sort of stagnant for the last few months for various reasons that Blake briefly goes into. I met Bart for breakfast yesterday morning, and after hanging out for a while, we went on over to the foundation and met pretty much all day to talk about the structure and goals of sfx and the relationship of the project with Mozilla (which relationship has been made more firm; we’re an officially supported project now rather than sort of a bastard stepchild snuck in and dumped on the sysadmins very much understandably to their chagrin). It was a good day, I thought.

    Afterward, Bart and Chris and I went out for dinner (I had jerked chicken for the first time ever and am glad to report that it’s very good) to talk about the services my new company’s going to be providing. Discussing the stuff and having face to face time with Bart and others in my new company is the reason my stay out here is a little extended. We walked around near the Stanford campus, went to a nifty Borders bookstore, which we walked through to get to the Apple store, where we hovered around a $2000 monitor the size of basically an IMAX movie screen and brainstormed about logos and other things. Then I came on home, it now being about 10:00 and my being very tired from hardly having slept the night before, and watched some TV and went to sleep.

    I was watching VH1 while getting dressed and waiting to go for breakfast yesterday when a Gwen Stefani video came on in which she was doing sort of a takeoff of Topol singing “If I Were a Rich Man” in Fiddler on the Roof. The video had a pirate theme and was very weird. Just before that one, I had seen an Eminem video that was sort of an homage/take-off/rip-off of “Toy Soldiers.” It was sappy (for Eminem) and sort of cliche and all “Ok, rappers, stop killing one another” but was sort of catchy.

    Mleeka called yesterday to report that she was at the doctor with Lennie, who had begun shitting blood. They’re doing lab work to see if they can figure out what it is. The blood is bright red, which is apparently much better than if it were darker; darker blood means it’s coming from further up in the gastrointestinal tract and is more of an internal thing. Lennie also had a rash come back, which rash in the past has been deemed a reaction to so far two different common antibiotics. So maybe she’s allergic to the third they’ve put her on. Here’s hoping that’s all it is. Mleeka says she’s acting as happy as ever and doesn’t seem to be feeling bad. That’s good, at least. I’m sort of paralyzed here, waiting for a call from Mleeka any minute to tell me the status, that maybe — whoops — she just accidentally spilled some fingernail polish into Lennie’s diaper and everything’s ok and my baby’s not going to croak while I’m here alone in California petrified at the thought on my free day today of venturing out to San Francisco and possibly inadvertently joining a horde of hookers and whinos and anticipating skipping the Super Bowl to talk about Web services (provided I make it back from San Francisco) and all these other fun, scary, stupid, stupid things that make me feel like a real deadbeat dad for being out here doing while my baby, please, please, baby, be ok. Be ok.

    For a while now, I’ve been reading Heather Armstrong’s blog. She’s sort of an Internet celebrity because she lost her job for blogging about her job. She’s certainly not the only one to suffer this fate, but she’s perhaps the most famous. She’s a good writer and has many stupid unimportant things to say but also has many funny and tender things to say. Take for example this month’s letter to her daughter, who just turned a year old, in which Heather articulates in just the most gorgeous ways imaginable some of the tender sorts of things parents feel for their little children, which sort of tears me up, sitting here thinking about my poor caterpillar slobber monkey cheerfully shitting blood and me not able to get her belly or share a vaguely tug-of-warrish chew of her stuffed sheep as we like to do or roar together or even just change a diaper so that Mleeka, who’s there alone with her and afraid and without my immediate proximal support, can maybe get a little emotional break.

    California, Here I Come

    February 3rd, 2005 by daryl

    At 2:30 today, I leave for California for a week, ripping myself away from my quickly-developing gorgeous child without whose daily attempts to bite my nose off and to ravage her stuffed sheep Lela and newfound ability to butterfly wave with her catterpillar hands I’m not entirely sure I can sustain a worthwhile existence. Here are some of my concerns:

    • Lennie will forget who I am or decide she doesn’t like me when I return. I know this is a stupid worry because a friend had to be out of town for two months with only a couple of visits home and his daughter, roughly the same age at the time that Lennie is now (a little younger) remembered him and was thrilled when he returned, etc. Still, I worry.
    • Hayseed non-travelled bumpkin that I am, I will be overwhelmed at the airport and will:
      • miss my connecting flight.
      • be taken advantage of by some greasy city slicker.
      • get lost.
      • have my luggage lost.
      • catch some horrible disease from the dandruff blowing like snow off a cab-driver’s seat as he drives me from San Francisco to Mountain Valley.
      • do something stupid like put my laptop somewhere where it gets magnetized and formatted or leaving it out on the airplane wing while I bend over to tie my shoe, where it goes rattling off to its destruction upon takeoff.
      • be subjected to a body cavity search because I’m a scruffy sort of burly male with a goattee and long, pointy and quite possibly sinister (but for the fact that they’re red/blonde) eyebrows travelling alone.
      • have a heart attack at the daunting prospect of managing all these really quite mundane but for non-adventurous homebody me utterly terrifying experiences on my own.
      • be laughed at by hookers and whinos for reasons I don’t understand but that really bother me for reasons I can vaguely grasp but can’t quite articulate, their being hookers and whinos and so who cares whether or not they laugh at me, but the fact that they’re hookers and whinos making their laughter all the more insulting and painful, though of course I don’t mean to belittle hookers and whinos, who mostly are in these horrible circumstances for reasons they’d undo if they could, which of course is why they’re inclined to laugh at bumpkins weeping fetally in the corner of an airplane terminal because their luggage has been lost and by gosh they just want their mommies or their wives or maybe some better-travelled friend to be there to tell them where to go and which line to stand in and to help hail a non-dandruffy taxi while telling jokes and pointing out neat bits of local color and generally putting them at non-fetal ease even though they’re way across the country, having never been further west than Houston, away from their caterpillar babies and comforting wives (or, if their wives are the ones directing and comforting and local-color-regaling them, their good friends).
    • Overwhelmed by the various airport debacles and generally terrified at the prospect of trying out new experiences on my own, I’ll spend the whole time I’m out there sitting depressed in my hotel room, afraid to venture out to see the bridge or the City Lights bookstore or all the weird cool people, much as I sat depressed and lonely and feeling really bad about myself one summer during high school at an athletic trainer’s camp I went to over a weekend, unable to venture out or to meet people unless it was absolutely required and supervised lest the icy hands of fear and social anxiety and something akin to but not in any way actually agoraphobia kneaded my heart and my guts and helped to shape the timid, trembling little traveller rabbit I’ve become today.
    • Because I’m so weird about trying new experiences, I’ll be viewed as strange and weak by those around me both on the trip and back at home and will be quietly and politely pitied.
    • I’ll get lost. This is inevitable, and I might as well prepare for it. As a result of my getting lost and being too embarrassed and frightened to ask anybody for help lest they think me a bumpkin and pity me, I’ll find an overpass and go to live there wrapped in newspapers and sheltered from the wind by a refrigerator box pretty much abandoned by a fellow overpass-dweller who does not sound well at all, but it’s a dog-eat-dog world, so finders keepers. In maybe twenty years, embittered by the loss of my by comparison pastoral life back in the shadow of the Smoky Mountains with the loss of my caterpillar daughter and the disappointment and sadness inflicted on Mleeka by my being incompetent to navigate my way back home, with a beard down to my belly button and straw in my hair and muttering gibberish and swatting at things no one else can see, I’ll find myself arm in arm with hookers and other whinos pointing and laughing at some new pathetic rube come down to our little hell on earth with his furrowed pointy brows and jeans tattered from getting caught on a loose piece of metal in a bathroom stall and a look of worry and a sort of inner hatred and utter, utter desolation that, twenty years past, was very familiar but that now is simply a little vignette of pain of the type that it is my only solace to make light of.

    But it’s not all bad. If I can get around some of these concerns, there’s much to look forward to. I’ll be in meetings with some very competent and bright people hashing out things that we hope will make browsing the Web better for everybody. I’ll get to say I’ve been to the other side of the country, and if I’m lucky, I will get to see the bridge (here’s hoping I don’t soon find myself living under it) and the bookstore and the weird cool people. I’m really very much looking forward to it, but my eagerness is tempered by or more like surrounded by and buried in a dread that makes my chest and stomach feel acidic and weak and my heart beat faster and harder.