On-the-fly CSS Compression in PHP
Web site optimization experts suggest that webmasters try to minimize the number and size of HTTP requests necessary to serve web pages. Web designers often use multiple CSS files because they are easier to manage, but this requires as many HTTP requests as there are CSS files.
This free script serves all your CSS files as a single HTTP resource, minified (by removing comments and extraneous whitespace), and gzip-compressed. It also requests browsers to cache the CSS content for at least a day before trying to fetch a new version.
The best part is that this does not pre-process the files, so it does not add any steps to your deployment process. It’s licensed free for commercial and non-commercial use, with attribution requested.
HOWTO Obtain metadata for a book given its ISBN using Amazon Web Services in PHP
This is a quick snippet I put together for an academic project. To be able to write this, I had to go through several documentation resources, for what is essentially a single web service method call. I figured it would help if I shared my PHP code.
<?php
class ISBN {
function getMetadataFromIsbn($isbn) {
$awsAccessKeyID = 'YOUR_ACCESS_KEY_ID_HERE';
$awsSecretKey = 'YOUR_SECRET_KEY_HERE';
$awsAssociateTag = 'YOUR_ASSOCIATE_TAG_HERE';
$host = 'ecs.amazonaws.com';
$path = '/onca/xml';
$args = array(
'AssociateTag' => $awsAssociateTag,
'AWSAccessKeyId' => $awsAccessKeyID,
'IdType' => 'ISBN',
'ItemId' => $isbn,
'Operation' => 'ItemLookup',
'ResponseGroup' => 'Medium',
'SearchIndex' => 'Books',
'Service' => 'AWSECommerceService',
'Timestamp' => gmdate('Y-m-d\TH:i:s\Z'),
'Version'=> '2009-01-06'
);
ksort($args);
$parts = array();
foreach(array_keys($args) as $key) {
$parts[] = $key . "=" . $args[$key];
}
$stringToSign = "GET\n" . $host . "\n" . $path . "\n" . implode("&", $parts);
$stringToSign = str_replace('+', '%20', $stringToSign);
$stringToSign = str_replace(':', '%3A', $stringToSign);
$stringToSign = str_replace(';', urlencode(';'), $stringToSign);
$signature = hash_hmac("sha256", $stringToSign, $awsSecretKey, TRUE);
$signature = base64_encode($signature);
$signature = str_replace('+', '%2B', $signature);
$signature = str_replace('=', '%3D', $signature);
$url = 'http://' . $host . $path . '?' . implode("&", $parts) . "&Signature=" . $signature;
$rawData = file_get_contents($url);
$metadata = simplexml_load_string($rawData);
if (isset($metadata->Items->Request->Errors)) {
return $metadata->Items->Request->Errors;
} else {
return $metadata->Items->Item;
}
}
}
?>
Press Coverage of my Intern Work at Google
It’s been exactly a month since my feature launched on Google Books. I went on an ego-surfing trip to see who had covered it. Here’s what I found.
You know what I did last Summer?
This, covered at the Official Google Book Search Blog.
While it is easy to share links, photos, videos, and opinions on the Web, sharing books with your friends online used to be tough — and tougher even, to share individual clippings from a book. This summer, I worked with the Book Search team to add clip-sharing features to Google Book Search.
You can now highlight a section of text in any public domain book in Book Search, create a clip from it, and share it with the world. You can post your favorite clips to your blog along with a personal annotation, collect them in a Google Notebook, or share them with friends anywhere you decide to embed the link. Your clip looks exactly as it appears in the book, or if you prefer plain text, we have that too.
Also at the Official Google Blog, about collecting, sharing and discovering new books.
We’ve also launched a way to let users, select, copy and embed segments of public domain books (like the Newton quote) in any web page. We hope to make it as easy to blog and quote from a book as it is from any web page. Like many innovations at Google, a stellar summer intern worked on this.
Of course, no project is a single-person effort: Bill Schilit, my mentor; Nathan Naze, JavaScript God; Adam Mathes, Venu Vemula, and the rest of the Book Search team laid the foundation and were an integral part of this feature.
Timezone issues in Google Calendar widget fixed. Or so I think. Maybe.
Lots of you reported timezone errors in my Google Calendar Dashboard Widget. I thought I’d fixed it in 2.0 with some changes to the date parsing code, but it turned out that only worked for certain timezones. So here is another version with solely a timezone bug fix. I believe this should be the end of all troubles, but who knows.
Go forth, download v2.1, and let me know how it goes! If you still encounter any issues, please let me know.
If you’re a programmer, you might appreciate knowing what was wrong: the JavaScript parseInt function expects a radix as its second argument. (Radix is the base to which numbers should be parsed, e.g. decimal, octal or hex.) If you don’t provide a radix, the function guesses a radix based on the string you pass to it. If the number starts with 1-9, then the radix is assumed to be 10; if it’s 01-09, then it’s octal, and 001-009 are parsed as hex. So the timezone parsing was being affected by this for all the 01-09 hours of difference. Long story short, I added the radix explicitly, and things should be OK now.
Google Calendar Dashboard Widget Updated to version 2.0
This long-pending update to my Google Calendar Dashboard Widget is now finally ready!
Changes in Version 2.0
- There were some problems handling time-zones in version 1.0 for some users. These issues have been (hopefully!) fixed in version 2.0.
- A highly-requested feature was to be able to look-ahead several days into the future, not just today and tomorrow’s events. Version 2.0 lets you preview up to one week ahead of today.
- The top part of the widget now features a button that takes you to Google Calendar in a browser. Trivial, yet highly useful, feature.
Download this free update if you’re using version 1.0. And keep the comments flowing in!
Related posts: Announcing the Google Calendar Dashboard Widget.
Announcing the Google Calendar Dashboard Widget
In the tradition of writing gadgets for Google Desktop and other Google properties, here’s one more from me: the Google Calendar Widget for Mac OS X Dashboard.
Since my switch to the Mac, I’ve been missing Google Desktop and using Dashboard more and more. And a calendar’s a nice thing to keep an eye on from time to time. So, without much further ado, here’s the gadget, oops, widget!

Find Out What Your Phone Number Spells
I clearly have too much time on my hands. Or so it would seem by looking at what I’ve been doing the last hour. I just got a new phone yesterday. And I was curious as to what it might spell. So I wrote up a script to show all the names your phone number could spell and picked a choice few for myself. I would post my most interesting findings here, but I already get way too many phone calls to post my new number on the Wild, Wild Web.
Google Desktop now includes Google Calendar Gadget
A new version of Google Desktop released today. (For those who came in late, I worked on Google Desktop last year, and have been writing plugins for it for some time now.) When Google Calendar released, I wrote a plugin for it too.
Since my plugin was licensed under an open-source license, Google added features to it and included it in the official download. What’s more, I even get credited in the source code. Go, Google! — kudos to the nice people in the Desktop/Calendar teams.
Macs Aren’t So Secure, After All!
Well, what’s to stop someone from picking up your PowerBook or MacBook Pro and running away? Macs aren’t really secure now, are they?
Given that I’ll soon be moving cross-country to work at Google, I felt a little insecure about my laptop: the many ways in which it could be stolen. I’m not the kind who would use one of those chain-locks at all times, so I devised a software solution.
I wrote up a combination of two scripts, a shell script to run on your laptop, and a script to put on a web server somewhere else. The idea is that the laptop will keep informing the server about itself, and a stolen laptop may thus be recovered. It reports back the obvious stuff such as network names, what ISP it’s connecting to, and a traceroute to Google (so you can look it up backwards to see where it went.) It also sends back screenshots of the current user — so you can see what the thief has been upto! Perhaps you could catch a glimpse of an email account, an IM window, a website — something that can help you track down the thief.
Go check it out, it’s in my list of projects as Laptop Theft Protector. As usual, free as in beer, free as in freedom. In this case, it’s also free as in puppy (meaning you will have to spend some time with it.) And, as I’ve come to believe, the best things in life run only on a Mac. Don’t try this on Windows. Or Linux.
Goocal = Google Calendar + Google Desktop
Google Calendar released yesterday. And everyone knows about it today!
But do you know what’s happening today? Especially in your own life? Go track your Google Calendar events in Google Desktop with Goocal. Free as in beer, free as in freedom, as everything else has been. Look out for more features soon!
Impeccable Timing
Last week, I wrote a plug-in for viewing Del.icio.us bookmarks in the Google Desktop Sidebar. Then I submitted it to Google, and it was being tested by them for a couple days. Then they approved it, and added it to the listing on their website as well as in a blog entry. I had already been receiving feedback from the curious beta testers on the Google Desktop Developers group.
So far, so good.
Then, exactly on the day Google pushed an update to their servers (which contained the new pages for my plugin), Del.icio.us announced that they were being bought by Yahoo! Not that it made a huge lot of difference; del.icio.us is still the same, and as useful as it always was.
But it’s a little ironic that I ended up writing a product that put a Yahoo! property inside the Google Sidebar. Not that there’s anything wrong with that — but you know, they’re like rivals and stuff.
Coverage Elsewhere:
And all this happened on exactly the same day. Like I said, the timing was impeccable!
Movies Plugin for Google Desktop
With the latest release, Google Desktop 2.0 introduced script plugins. That means that it’s now easy as ever to create sidebar panels. So I went ahead and created a Movies plugin — you specify a zip code, and it will display customized movie listings for theaters near your home. You can also filter by genre, MPAA ratings, or user ratings, and sort by popularity or ratings.
Worth a try! It’s available free: Google Desktop Movies Plugin.
It has also featured in Google’s Plugin Library, and on the Google Desktop Blog as Plugin of the Week.
Not bad for half a day’s work, eh? That’s putting the Thanksgiving break to fruitful use.
Spindle Search featured by Google
Thought I’d post a quick note to tell ya folks that Google added Spindle Search to their list of featured plugins today. Go! http://desktop.google.com/plugins/cddvd.html
.Net Wrapper for Google Desktop Search
I’ve been reading the Google Desktop Developer Forums pretty often, partly to see what people have to say about my Spindle Search plugin, and partly to help whenever I can.
I realized that a lot of C# / .Net developers are reinventing the wheel when writing code for interoperating with the Google COM object. So I thought, why not separate that into a library (I already had the code written as part of Spindle Search.)
So there’s now a new project, .Net Wrapper for Google Desktop Search, on my site.
CD / DVD Spindle Search
I’ve been a huge fan of Google Desktop Search, especially seeing how fast it is over the traditional file system search in Windows. But what I noticed it lacked, was the ability to index removable drives such as CDs, DVDs and external hard-disks. Even if it did index them, there is always the problem that the file might be unavailable when trying to retrieve it, simply because the CD is in a spindle, not in the drive.
But Google had a solution: they made their API accessible, so I wrote a plugin for it. Spindle Search now lets you add CDs, DVDs and other media to your Google Index, and then comes up with a dialog when you search for them, telling you where to locate the file and disk.
Go take a look, tell me what you think. The forums are waiting!
Data Backup for Home Users
<rant>Why isn’t there a decent piece of software that lets home users backup their hard drives every once in a while? Or if there’s one, why can’t I find it anywhere? I can’t hire an IT department, so anything more than 3 or 4 clicks is not worth it.</rant>
So I finally gave up and wrote a homegrown tool – the bit about programs scratching a developer’s personal itch is so true! It’s trivial enough to not call it a piece of “software” or even a “utility”. I had the following objectives in mind for my backup strategy:
- The backup should reside on DVDs. When my machine goes six feet under, I cannot fiddle with peripherals nobody else has. I want a disk I can carry in my jacket pocket, walk over to school, and have my files with me.
- Restoring should only involve copying the files back: no extracting from archives (Corollary to Murphy’s Law: In any archive copied to optical media, exactly one bit gets toggled by an invisible evil force, thus rendering said archive unusable.)
- Incremental backups for intermediate days: copy only those files that changed since the last backup.
- I can’t afford to pay for a program for such a simple task.
- Nice-to-have: have it automatically do this for me every X days.
Unfortunately, I found none that satisfied the given criteria. It didn’t help that my primary platform is still Windows. I found Mike Rubel’s article on Incremental Backups with rsync nice and informative, but useless on Windows because NTFS won’t support hard links.
So I ended up writing this tool that looks at the last-modified date and copies over everything modified after a given date X to a temporary backup directory. Then, I just burn that to a DVD. Who said good solutions are complicated?