stop-sopa.js – along with WordPress, Blogger, and Typepad plugins

SOPA (the Stop Online Privacy Act) is a really bad thing that potentially threatens this wonderful thing we created called the internet. If you don’t already know about it I won’t rehash it all here, but you can check out this post from Electronic Frontier Foundation.

At Torbit, we saw what other companies like Reddit and Craigslist were already doing and wanted to help other people participate in protesting SOPA. What we came up with is stop-sopa.js, which is an open source widget to add an informative modal window to your site with information about SOPA and how to contact your local representatives to tell them you oppose this new bill. By default it will only be displayed on January 18th from 8am–8pm EST (1300–0100 UTC). It’s available as a WordPress plugin, Blogger widget, Typepad widget, and a simple javascript snippet. Check out the screenshot below to see what it looks like or click here to try it out.

stop-sopa.js

Help protest this threat to the internet. Notify your representatives, spread the word, and protest on your site. Stop censorship by stopping SOPA!

Posted in General | Tagged , , , | Leave a comment

Find the Time to First Byte Using Curl

I was recently looking for an easy way to find the time to first byte (TTFB) for a given url using curl. I wanted to run some script based tests for a bunch of urls over time. I ended up coming up with the following:
curl -w "Connect time: %{time_connect} Time to first byte: %{time_starttransfer} Total time: %{time_total} \n" -o /dev/null [url to test]

This gives you something like the following:
curl -w "Connect time: %{time_connect} Time to first byte: %{time_starttransfer} Total time: %{time_total} \n" -o /dev/null www.google.com
Connect time: 0.402 Time to first byte: 0.453 Total time: 0.475

Hope this is useful to someone else.

Posted in Code | Tagged , , | 1 Comment

PHP str_replace_last function

I recently found myself in need of a way to replace the last (and only the last) occurrence of a substring within a string. Basically exactly str_replace, but only on the last occurrence of the needle within the haystack. I came up with this quick solution. Feedback welcome.

function str_replace_last( $search, $replace, $subject ) {
    if ( !$search || !$replace || !$subject )
        return false;
    
    $index = strrpos( $subject, $search );
    if ( $index === false )
        return $subject;
    
    // Grab everything before occurence
    $pre = substr( $subject, 0, $index );
    
    // Grab everything after occurence
    $post = substr( $subject, $index );
    
    // Do the string replacement
    $post = str_replace( $search, $replace, $post );
    
    // Recombine and return result
    return $pre . $post;
}

Hope someone else finds this useful.

Posted in Code, php | Tagged , | 2 Comments

Torbit is Hiring!

My current company Torbit is growing and we’re looking for a few good people to join us. If you want to help us make the web a better place let us know.

Here are a few quick job descriptions of what we’re looking for:

Systems administrator
Our ideal candidate would have experience building and scaling large distributed infrastructure across multiple data centers. Your job would include architecting new infrastructure, helping us set up global data centers and performing ongoing maintenance. You would be expected to build redundancy, active failover and monitoring into our system and find ways for us to improve performance at the server-level. We would like to see experience with Chef along with a working knowledge of Anycast, NGINX, MySQL and Node. Experience with SPDY, tweaking TCP slow-start and other performance optimizations a plus.

Frontend PHP developer
We need a front-end developer who will be responsible for the public-facing parts of our application. Responsibilities would include our marketing site, account system, billing system, DNS control panel, reporting dashboards and lots more. We would expect you to be good with JavaScript, HTML and CSS. A performance background and good design sense a plus.

Performance engineer
For this position, we want someone who has a strong background in front-end performance. This job will be to help us research and implement new techniques for speeding up websites. Strong PHP and JavaScript skills required. Experience working with large scalable systems a plus.

If you don’t fit into one of these but are interested in what we’re doing that’s ok. We’re looking for smart people interested in solving interesting problems. We’d love to hear from you if that sounds appealing. Feel free to email us at jobs@torbit.com and check out the Torbit blog post for more information.

Posted in work | Tagged , | Leave a comment

How to programmatically find the continent from a given city or state

I recently ran across a somewhat unusual problem. I needed to find a programatic way to convert a string that could be a city or a state name into the continent that the city or state belongs to. I Googled around a bit and couldn’t find an obvious solution, so I thought I’d write this up in hope of helping the next guy.

What I ended up doing is using the Yahoo! GeoPlanet API. This allowed me to do a query of my city or state name and get a place resource, then use that to find the continent that the place resource belongs to.

So first things first, you’re going to need an app id from Yahoo!, so if you don’t already have one you’ll need to get one. Then you just need to make a request like the following:
http://where.yahooapis.com/v1/places.q(CITY_OR_STATE)?appid=YOUR_APP_ID
Where CITY_OR_STATE is the query term you’re searching for and YOUR_APP_ID is the Yahoo! app id from above. Then you’ll get back something like the following:


<places xmlns="http://where.yahooapis.com/v1/schema.rng" xmlns:yahoo="http://www.yahooapis.com/v1/base.rng" yahoo:start="0" yahoo:count="1" yahoo:total="300">
<place yahoo:uri="http://where.yahooapis.com/v1/place/2488042" xml:lang="en-US">
<woeid>2488042</woeid>
<placeTypeName code="7">Town</placeTypeName>
<name>San Jose</name>
<country type="Country" code="US">United States</country>
<admin1 type="State" code="US-CA">California</admin1>
<admin2 type="County" code="">Santa Clara</admin2>
<admin3/>
<locality1 type="Town">San Jose</locality1>
<locality2/>
<postal/>
<centroid>
<latitude>37.338470</latitude>
<longitude>-121.885788</longitude>
</centroid>
<boundingBox>
<southWest>
<latitude>37.117840</latitude>
<longitude>-122.160027</longitude>
</southWest>
<northEast>
<latitude>37.555859</latitude>
<longitude>-121.535393</longitude>
</northEast>
</boundingBox>
<areaRank>6</areaRank>
<popRank>12</popRank>
</place>
</places>

You want to grab the woeid (in this case 2488042) for the next part. Next, we need to lookup the continent this place resource belongs to. To do this we make a request like so:
http://where.yahooapis.com/v1/place/THE_WOEID/belongtos.type(29)?appid=YOUR_APP_ID
Where THE_WOEID is the woeid we found in the last step (2488042 in this example) and YOUR_APP_ID is your app id again. This should return something like the following:

<places xmlns="http://where.yahooapis.com/v1/schema.rng" xmlns:yahoo="http://www.yahooapis.com/v1/base.rng" yahoo:start="0" yahoo:count="1" yahoo:total="1">
<place yahoo:uri="http://where.yahooapis.com/v1/place/24865672" xml:lang="en-US">
<woeid>24865672</woeid>
<placeTypeName code="29">Continent</placeTypeName>
<name>North America</name>
</place>
</places>

Where North America is clearly what we want to pull out of it.

I was doing this in PHP, so here’s a quick and dirty PHP example:

function continent_lookup( $search ) {
    if ( strlen( $search ) == 0 )
        return false;

    $search = urlencode( $search );

    $app_id = 'YOUR_APP_ID';

    $res = file_get_contents( "http://where.yahooapis.com/v1/places.q($search)?appid=$app_id" );
    preg_match( "/<woeid>([0-9]+?)<\/woeid>/", $res, $match );

    if ( !$match )
        return false;

    $woeid = $match[1];

    $res = file_get_contents( "http://where.yahooapis.com/v1/place/$woeid/belongtos.type(29)?appid=$app_id" );
    preg_match( "/<name>(.+?)<\/name>/", $res, $match );

    return $match[1];
}

Hope this helps someone else out there. Let me know if you have any feedback.

Posted in Code, php | Tagged , | Leave a comment

How Brad Schroeder’s DJ Service In Springfield, IL Nearly Ruined My Wedding

This is definitely going to be a rant.  If you come across this post and were considering hiring Brad Schroeder’s DJ Service in Springfield, IL – don’t.  If you’d like to know why, read the rest of the post, but I wanted to make sure this point gets across right up front.

I first met Brad Schroeder at a friend of mine’s wedding.  He did a pretty good job and seemed professional. When my wife and I were planning our wedding we got a long list of potential DJ services with a wide range of prices.  I talked to lots of them and we ended up deciding on Brad Schroeder’s DJ Service for two primary reasons.  First, he offered a relatively good price comparatively.  Even though he was charging us extra for travel (the wedding was in Glen Ellyn, IL) he still came out a bit cheaper than most of the other services we were looking at.  And secondly, he was the only DJ service that we had seen / heard at a wedding before, and we were happy with his services there (as were our friends who hired him for the most part).

This turned out to be a big mistake though.  We had several problems leading up to the wedding.  He was very difficult to get a hold of by phone in the weeks leading up to the wedding, he kept forgetting things we’d discussed, etc.  It was on the day of the wedding though that the size of the mistake really came to light.  Not only was Brad not coming himself to DJ our wedding (which he had told me he would), but the “other guy” he sent to DJ the wedding was sent to the wrong hotel.  And not just a little wrong, but a lot wrong.  The hotel he went to was more than 3 hours away from the hotel where our wedding was located. This was hard to believe because Brad Schroeder had written the hotel in Glen Ellyn in our contract himself and had charged me extra travel expenses to get to it.  Even worse – we didn’t find this out until about an hour before our wedding when we got a call from the very confused DJ that was sent to the wrong hotel.

Needless to say this put us in a pretty tough situation, especially since Brad Schroeder’s service didn’t even offer a replacement DJ.  We were trying to do pictures and get the last details of the wedding sorted out when we were faced with the option of waiting for this DJ to drive the 3 hours to get to the correct hotel (and 1.5 – 2 hours of reception without music or a DJ) or trying to find another DJ at the last minute that we know nothing about.  Luckily the hotel’s wedding coordinator had a DJ that was trying to get on their recommended vendors list and we were able to get someone on our short notice, although he was double the price we were originally paying Brad Schroeder’s DJ Service in Springfield, IL.  We decided to risk it and figured an unknown, possibly bad DJ was better than no DJ.

Against all odds the last minute replacement, Carl Linder of Linder Productions, turned out to be great.  He was nice, professional, and still managed to accommodate most of our requests (even a few unusual ones) with the short notice he had.  My wife had also prepared a CD of most of our special songs (cake cutting, first dance, etc) because we had had so many issues with Brad Schroeder’s DJ Service before – which also turned out to be a life saver.  In the end we had a great wedding and our replacement DJ was even better than Schroerder’s DJ Service ever would’ve been.

Unfortunately the story doesn’t end there, though.  We had paid Brad Schroeder’s DJ Service up front at a previous meeting at a Denny’s in Springfield, IL.  Needless to say we felt we deserved to get our money back, and the difference in DJ fees, after he failed to show up to the correct location and perform his services.  You’d think after such a horrible mistake that was clearly his fault (the location was listed on the contract that he wrote and we both signed) that he’d be very apologetic and accommodating.  However, you would be wrong.  While initially he sounded like he’d be willing to correct his mistake, it wasn’t long before he wasn’t returning my calls and I started getting called by his attorney instead.

Luckily my brother is a licensed attorney in Illinois and was willing to help me out.  Long story short, it took a lawsuit filing and 10 months before I was able to get my money back from this guy.  We still ended up losing the court costs to file, but were eventually able to settle out of court to get our money back.  What a terrible way to do business.

If you’re planning a wedding or other event in Jacksonville, Springfield, or the surrounding area in IL and looking for a DJ, look elsewhere.  Brad Schroeder’s DJ Service in Springfield, IL nearly ruined my wedding and was a huge pain to get my money back from later.

Sorry for the rant, but it needed to be said.

Posted in Rants | Tagged , , , , , , , , | 10 Comments

Moving to California


I’m excited to say that my wife and I have made the big move to Sunnyvale, California. Moving is always a big mix of bitter and sweet, excitement and craziness.

It was definitely a hard choice to make. I lived in the Boulder area for over four years and loved it. The community in and around Boulder is one of a kind. People truly want to help each other succeed and it’s very easy to get plugged in to the great people there. It’s also full of great views, hiking, and tons of sun. I still think it’s a great place to build a company and is an especially great community for first time entrepreneurs to find their legs. While getting started with Torbit, though, my partner and I had a tough choice to make. Where did we want to build this company?

There wasn’t any one reason we decided to move, it ended up being a mix of lots of different factors (both personal and professional). Josh and I wanted to grow our professional network in the Bay area, my wife and I were looking for a change in our personal lives, my wife was going through a bit of a career change, and we didn’t think there would be any better time to move out to CA (we don’t have kids or a house yet). In the end we decided this company would probably be a good fit for CA and we were personally ready to make that change.

It was fun for me to look back at my first post after I arrived in Boulder. The car was again packed pretty ridiculously, but this time we had two cars to drive out. My then girlfriend, now wife came along for the ride as well. And of course, the drive was mostly tedious and boring, but when we got here there was a lot of great stuff to see.

I look forward to meeting new people, finding new restaurants, and seeing what great opportunities CA will bring.

Posted in General | Tagged , | 3 Comments

How To Detect Transparency In PNG Images

I recently came across a problem where I needed to check for transparency in PNG images using PHP. After some digging with the help of my partner Josh, we came up with the following php function:

function png_has_transparency( $filename ) {
    if ( strlen( $filename ) == 0 || !file_exists( $filename ) )
        return false;
    
    if ( ord ( file_get_contents( $filename, false, null, 25, 1 ) ) & 4 )
        return true;
    
    $contents = file_get_contents( $filename );
    if ( stripos( $contents, 'PLTE' ) !== false && stripos( $contents, 'tRNS' ) !== false )
        return true;
    
    return false;
}

The first file check:
ord ( file_get_contents( $filename, false, null, 25, 1 ) ) & 4
will check for transparency in a 32-bit PNG. The second check
stripos( $contents, 'PLTE' ) !== false && stripos( $contents, 'tRNS' ) !== false
works to detect transparency in 8-bit PNG’s. Big thanks to this article which expains how these parts work in a bit more detail.

Depending on how likely you are to have transparency (or 32-bit png’s) you might want to modify this function to only do one file access, but the advantage here is that if it is a 32-bit png with transparency we only need to read in part of the file. This was faster in my early testing of a sample of our images, but your results may vary.

Hope this helps someone else out there.

Posted in Code, php | Tagged , , , , | 1 Comment

One time use email addresses

Recently I threw together a tool to simplify my sign up on other services.  It’s a script that allows me to use an email address one time, and then ignore all future emails to that address.  I often use it for signing up to new services so that I can get the confirmation email, but not get a bunch of spam / bacon I don’t really care about.  I set it up with a custom domain so that I can use anything at that domain as an email address.  For example, test1@mycustomdomain.com, test2@mycustomdomain.com, and anotherdumbemail@mycustomdomain.com.

The interesting part of it, though, is that the emails all dump to a PHP script.  This script looks at the email address it was sent to, and checks a database to see if that email address has been seen before or not.  If it hasn’t, it will forward that email to my “real” email address.  If it has, it will ignore it.

This has been super helpful when making test accounts on services too as it’s easy to get another email address, but I don’t have to worry about checking a weird email account or getting a bunch of spam afterwards.  Just thought I’d mention it in case anyone else out there does a lot of this stuff.

Posted in Code, php, Random Ideas | Tagged | 2 Comments

2010: A Year in Review

2010 was a pretty big year for me.  A lot of changes including:

  • Got married!
  • Moved into our first house (renting not buying)
  • Left my first web startup (IntenseDebate)
  • Started a new company with Josh Fraser called Torbit
  • First “real” car accident
  • First jury trial
  • Turned 25 (a quarter century old!)

A lot of good and a lot of bad this year.  I look forward to the new year and the changes it will bring.

Posted in Introspective | Tagged , , | 2 Comments