Holiday Greetings

I wanted to send some sort of holiday greeting to my friends, but it is so
difficult in today’s world to know exactly what to say without offending
someone. So I met with my attorney yesterday, and on his advice I wish to
say the following:

Please accept with no obligation, implied or implicit, my best wishes for an
environmentally conscious, socially responsible, low stress, nonaddictive,
gender neutral celebration of the winter solstice holiday, practiced with
the most enjoyable traditions of religious persuasion or secular practices
of your choice with respect for the religious/secular persuasions and/or
traditions of others, or their choice not to practice religious or secular
traditions at all.

I also wish you a fiscally successful, personally fulfilling and medically
uncomplicated recognition of the onset of the generally accepted calendar
year 2006, but not without due respect for the calendars of choice of other
cultures whose contributions to society have helped make America great (not
to imply that America is necessarily greater than any other country or is
the only “America” in the western hemisphere) and without regard to the
race, creed, color, age, physical ability, religious faith or sexual
preference of the wishee.

By accepting this greeting, you are accepting these terms:

  1. This greeting is subject to clarification or withdrawal.
  2. It is freely transferable with no alteration to the original greeting.
  3. It implies no promise by the wisher to actually implement any of the wishes for her/himself or others and is void where prohibited by law, and is revocable at the sole discretion of the wisher.
  4. This wish is warranted to perform as expected within the usual application of good tidings for a period of one year or until the issuance of a subsequent holiday greeting, whichever comes first, and warranty is limited to replacement of this wish or issuance of a
    new wish at the sole discretion of the wisher.

Disclaimer: No trees were harmed in the sending of this message; however, a
significant number of electrons were slightly inconvenienced.

New Year's Resolution

  1. Travel to two new continents.
  2. Lose the last 20 pounds lingering around my waste.

Regarding the first resolution I’ve started researching both destinations along with gear. As for destinations I’ve decided on visiting Europe and Asia. In Europe I’m hoping to visit Amsterdam and Prague with the possibility of Rome. In Asia I plan on visiting Dubai. As with any travels, especially international travel, much planning will go into these trips. I’ve targeted May or Jun for my Europe trip and next fall for my Dubai trip. I’ve started researching airfare, places to stay and required gear. Thus far below is what I have so far.

  1. Get a passport.
  2. Unlock my Motorola RAZR V3.
  3. Research and purchase international SIM card(s).
  4. Purchase a large back pack with enough room for gear, clothes, maps and some food. Preferably have a CamelPak built in.
  5. Purchase a Palm Pilot with Bluetooth and WiFi. Additionally, purchase translation software and a Bluetooth GPS unit with European maps.
  6. Research health insurance coverage in Europe and, if needed, purchase trip insurance.
  7. Purchase a new digital camera.

Have you traveled abroad? If so, what would you add to the list? I’m especially curious to hear from people who have traveled to the Eastern Bloc and the Middle East. I’m also extremely interested in what I should put on my list of sights to see and what I can safely ignore. Where should I stay? I hear hostels are the way to go for the most part in Europe.

My highest priority when choosing the gear above was mobility. I don’t plan on taking a laptop for both mobility and security reasons (I don’t want it getting stolen in a hostel). That’s also my reasoning behind purchasing a backpack and not taking a suitcase. I also plan on taking an analog notebook to write down directions, numbers, notes, etc.

As for the second goal, I’ve been slowly working my way down to 200 pounds from 265 pounds for the last 1.5 years. I’ve got a diet and exercise plan that works for me, it’s just a matter of focusing on it. I’ve also managed to change my eating habits to the point where when I quit dieting I’m able to maintain my weight. This is, obviously, the easier and less expensive of my two new resolutions.

IE continues to suck

As some of you may know I run a small picture hosting site. A user emailed me the other day to say that Internet Explorer was only allowing her to download images at BMP images, despite the image being a JPG or a GIF. Turns out this is a known issue. I figured that had to be a way to turn off caching via the HTTP headers and I think I have a solution. If you’re sending dynamic files via PHP give these headers a try.


// Your file's extension
$ext = 'jpg';

// Your file's name
$name = 'goofypicture.jpg';

// Your file's location
$src = '/path/to/'.$name;

header("Pragma: public");
header("Expires: 0");
header("Cache-Control: must-revalidate, post-check=0, pre-check=0");
header("Cache-Control: private",false);
header("Content-Type: image/".$ext);
header('Content-Disposition: inline; filename="'.$name.'"');
header("Content-Length: ".filesize($src));


Enotes 6.0 Launches

It is with great pleasure that I announce Enotes 6.0. This is the 6th major iteration of the site since I’ve come on board and is by far the largest undertaking thus far. This iteration includes, in no particular order, the following upgrades.

  1. Completely redesigned by PBDH
  2. Expanded the content catalogue by over 20,000 articles
  3. All code is PHP5 E_STRICT compliant (except the code in PEAR)
  4. Moved to a monthly subscription model
  5. Added thousands of lines of code, stylesheets, HTML and XSLT
  6. Numerous other enhancements, tweaks and upgrades

It’s taken our developer team just over four months to take this from concept to reality. This has included upgrading to PHP5 (no small feat when you have 60,000 lines of code that are all PHP4 OOP), installing and configuring additional webservers, installing and configuring a Google Search Appliance, completely rewriting the shopping cart and creating an automated rebilling system from scratch.

Needless to say this wasn’t a one man show. I’d especially like to thank Ian and Matt for putting in extra hours to make sure we launched before the new semester. The team at PBDH deserves many thanks for their prompt and professional design services. And, finally, I’d like to thank caffeine. Without our beloved coffee Brad, Alex, Heather, Brandi, Ian, Matthew and myself would have passed out a long time ago.

For comparison here is a screenshot of the old site.


A few family members have been asking what I want for Christmas. The answer is nothing. I’ve got more toys than I know what to do with as it stands. I’ve got more clothes than most women and I just bought two new pairs of shoes. But, for those who insist on purchasing me something for Christmas here is a short list of my “needs”.

Whatever you do don’t purchase me clothes or toys. I don’t need either. Also, don’t use my Amazon wishlist as reference it’s fairly outdated, though I won’t complain too much if I get a few DVD’s this year.

Before you think “Hey, I should get Joe something for Christmas” look at the last bullet point on this list and ask yourself if I really need what you were thinking about getting me.

Framework 0.0.7 Released

I’ve fixed a minor security hole in my PEAR version of the framework that I created for the article Understanding MVC in PHP. Everyone who is currently using Framework 0.0.6 or below should update their install immediately.

To upgrade:

$ pear upgrade ""

To install:

$ pear install ""

Instructions for visiting Detroit

  1. First, you must learn to pronounce the city name. It’s Deh-troit NOT
    DEE-troit. If you pronounce it DEE-Troit then we will assume you are from
    Toledo and here for the country Music hoe-down.
  2. Forget the traffic rules you learned elsewhere. Detroit has its own
    version of traffic rules… Hold on and pray!
  3. The morning rush hour is from 6:00 am to 10:00 am. The evening rush hour
    is from 3:00 pm to 7:00 pm. Friday’s rush hour starts Thursday morning
    Weekends are open game.
  4. If you actually stop at a yellow light, you will be rear-ended, cussed
    out and possibly shot. If you’re first off the starting line when the light
    turns green, count to five before going across the intersection. This will
    avoid getting in the way of cross-traffic who just ran their yellow light to
    keep from getting shot.
  5. Schoenherr can ONLY be properly pronounced by a native of the Detroit
    metro area. That goes for Gratiot too.
  6. Construction and renovation on I-94, I-96, I-75, I-275, I-375, The Lodge
    and The Southfield Freeways are a way of life and forever. Just deal with
  7. If someone actually has their turn signal on, it is probably a factory
    defect or they are “out-of-towners” .

  8. All old men (or women) with white hair wearing a hat have total
  9. The minimum acceptable speed on I-696 and I-275 is 85 regardless of the
    posted speeds. Anything less is considered downright SISSY. Oh, and don’t
    even think of allowing more than one car length between cars!
  10. That attractive wrought iron on the windows and doors in Detroit is NOT
    ornamental. DO NOT get out of your car to take pictures.
  11. Never stare at the driver of the car with the bumper sticker that says
    “Keep honking, I’m reloading”, he/she is.
  12. If you are in the left lane, and only going 70 in a 60 mph zone, people
    are not waving because they are so friendly in Detroit. I would suggest you
  13. I-275 and I-696 is our daily version of NASCAR.
  14. It’s not M-10, it’s “The Lodge”.
  15. That’s not a lake, it’s a pothole.
  16. If someone tells you it’s on Outer Drive, you better hope you have a
  17. The Michigan left turn is simple. If you want to turn left, go a 1/4 of
    a mile past your turn, get to the left, then make a left, then make another
    left, then make a right when you get back to the intersection where you
    wanted to turn left in the first place. NOW you have gone left.
  18. And those 2 really ugly arches over Telegraph???? DON’T EVEN ASK!! WE
    DON’T HAVE A CLUE!!!!!

A recent conversation on AIM

Josh: OC comes on soon 🙂
Josh: have you been watching that Reunion show?
Josh: I like it
Me: Sweet – maybe I’ll watch it on my new iPod while I’m taking a dump 🙂
Josh: lmao…nice
Josh: you bought a fancy one eh?
Me: I took the biggest dump ever today.
Me: Yeah.
Josh: FYI that’s GROSS
Me: A black one.
Josh: iPod or dump?

Google Search Appliance GB-1001 Review

A couple of months ago Brad came to me to discuss problems with the search on our site. Since our site features a ton of text it’s imperative that users can easily find documents in a quick manner. Up until recently we had been using MySQL’s FULLTEXT feature, which I’ve covered extensively in articles and at conferences. FULLTEXT simply wasn’t scaling in the manner in which we needed it to. As a result, I set out looking for something that would.

I think it’s rather telling that MySQL themselves do not use this feature to index their own site, instead using Mnogo Search. While looking for a solution for us I decided against open source solutions for two reasons.

  1. We would still, essentially, be rolling our own search solution, which would still have to be maintained and supported internally. With two full time developers (including myself) this simply wasn’t an option. We needed a “Plug and play” solution.
  2. Support is non-existent for ht://Dig, but is available for Mnogo Search, however this still left us configuring, installing and supporting hardware.

This left us with two options: a hosted solution (ie. or an appliance (ie. the Google Search Appliance). In the end we went with the GSA GB-1001 for a few reasons.

  1. Even with the hefty price tag of $30,000 (USD) it was still cheaper than a hosted solution.
  2. It’s supported for two years and, after the two years is up, we still get to keep the hardware.
  3. Since we host it internally we can quickly change the XSLT stylesheets, etc. without having to call up an ASP to make changes.

So the GSA arrived and there was much rejoicing. Until we booted up the machine and noticed that it had arrived with a dead hard drive. Google says that it’s perfectly okay if a single drive fails and that they normally don’t replace a GSA with only a single dead hard drive. Okay, that’s fine, but the thing arrived with a dead hard drive. For that much money I would think it should arrive in pristine working condition.

To top off my frustrations the box locked up twice within a 24 hour period. Obviously, I wasn’t putting this thing into production anytime soon. Come to find out this locking business is a known issue with a working patch. I flat out asked my Google rep why it wasn’t shipped with the patch and they said it was because it only affected some of the GSA’s. Great. In the end we shipped our GSA backed after they shipped out a replacement.

The second one arrived with four working hard drives, but also suffered from the locking issue, which Google quickly patched by logging in via SSH. SSH? Yes, the Google Search Appliance runs RedHat Linux.

So what exactly does the GSA run on? Well I’ll list the specs out for you.

  1. Quad 2.66GHz Intel Xeon
  2. 12GB of RAM
  3. Five 250GB Western Digital EIDE drives (Two 250GB RAID1 mirrors on a 3ware ATA RAID card and one hot spare)

In other words it’s a really beefy linux box (in a really dorky looking yellow case). Of course the box is all locked up so you can’t look on the inside and I wasn’t looking to void our support and warranty by opening the box.

So how does it perform? Well, after much tweaking of the XML interface, it’s pretty amazing. According to Google the GB-1001 will index 500,000 documents and is capable of performing 300 queries per second.

After the initial problems with the GSA I have two major complaints with it. The first is that the support is inadequate. For $15,000 per year I expect support to be better than email-only Monday through Friday during business hours. The second is that it didn’t ship with a SOAP interface. The main Google site has one, why doesn’t the GSA? Sure I can get the response back in XML, but a SOAP interface would have been much appreciated.

Other than those two issues and a few minor quirks I give the GB-1001 a high score. If you’re simply doing a site-wide search I don’t think you’ll find a more brain dead simple solution.

10 reasons why gay marriage should be illegal

  1. Being gay is not natural. Real Americans always reject unnatural things like eyeglasses, polyester, and air conditioning.
  2. Gay marriage will encourage people to be gay, in the same way that hanging around tall people will make you tall.
  3. Legalizing gay marriage will open the door to all kinds of crazy behavior. People may even wish to marry their pets because a dog has legal standing and can sign a marriage contract.
  4. Straight marriage has been around a long time and hasnÂ’t changed at all; women are still property, blacks still canÂ’t marry whites, and divorce is still illegal.
  5. Straight marriage will be less meaningful if gay marriage were allowed; the sanctity of Britney SpearsÂ’ 55-hour just-for-fun marriage would be destroyed.
  6. Straight marriages are valid because they produce children. Gay couples, infertile couples, and old people shouldnÂ’t be allowed to marry because our orphanages arenÂ’t full yet, and the world needs more children.
  7. Obviously gay parents will raise gay children, since straight parents only raise straight children.
  8. Gay marriage is not supported by religion. In a theocracy like ours, the values of one religion are imposed on the entire country. ThatÂ’s why we have only one religion in America.
  9. Children can never succeed without a male and a female role model at home. ThatÂ’s why we as a society expressly forbid single parents to raise children.
  10. Gay marriage will change the foundation of society; we could never adapt to new social norms. Just like we havenÂ’t adapted to cars, the service-sector economy, or longer life spans.