Prototype and script.aculo.us aka The Bungee Book 1
I thought it prudent to blog a bit about some of the technical books I’ve been reading of late so thus begins perhaps the first of several posts about my library:

I ordered Prototype and script.aculo.us by Christophe Porteneuve the other week directly from the publisher, the well-known Pragmatic Programmers. I highly recommend buying books directly from them as you can get a PDF copy for very little extra money. Who likes lugging around books all the time, anyway?
This book is a comprehensive guide to Prototype and script.aculo.us and covers both libraries from beginning to end. You need only have a basic understanding of JavaScript to dive in—which was perfect for me as I’m really weak on JS. The readability of this volume is perhaps its best quality. I can literally sit in bed and read this book cover to cover without feeling like I need to have my laptop by my side. It seems to have a larger ratio of words to code and the writing style of Porteneuve is refreshingly casual, friendly, and funny.
The book itself is not huge, about 400 pages, but its content that counts. And, thankfully, it doesn’t waste trees with pages and pages of reprinted documentation. Oh how I can’t stand buying a big fat technical book for $60, only to discover that half of its pages are reformatted documentation that’s freely available!
The “Bungee Book”, as the author refers to it, (Sidebar: Is this going to be a thing now? Every PragProg book has to be nicked named after its cover picture? Who gets to pick the cover pictures?), is a great read and I highly recommend it for your bookshelf.
Working around IE gif annoyances 1
Parts of an upcoming project make calls out to an external service that can take several seconds to respond. As everyone knows, the attention span of the average idiot web surfer is closer to a few nano-seconds. And so, we use AJAX loading indicator animated gifs to show the user something is happening.
However, several pages perform this call on their initial load. So an AJAX loading indicator won’t do the trick—the indicator has to appear on the preceding page in the navigation process. And so, we created some Javascript that would simply unhide an animated gift next to a “Next Step” button when the button was clicked. This provides some feedback to user that the next page is loading. (The user could, of course, note the status of their own browser’s load-indicator, but I suspected many wouldn’t.)
This seemed to be working great until solid IE testing began. We soon discovered that as soon as navigation away from the current page has begun, IE stops all animated gifs. The result is a rather unhelpful seized-up spinner-gif that actually makes the user think something went wrong.
So instead of an animated gif, we now use the lovely effect features of script.aculo.us to fade a non-animated hourglass icon in and out when the button is clicked. Some JS like this…
Effect.Pulsate(icon, {
duration: 100,
pulses: 95
});...results in something like this:

The net result is the same: the user knows something is happening behind the scenes. But now, at least, it plays nice with IE. Seems that IE lets JS effects like this go on even after the call to the next page has begun.
In retrospect, it might been best to ensure that our page loads didn’t call the external service directly. But rather, load the next page rapidly and then made an AJAX call out to trigger the slower service. That way, we could have avoided these issues all together and used the traditional, in-page AJAX loading animated gifs.
Oh well. There’s always version 2.0.
Exporting data from SQLite
I recently discovered that sqlite3 has a number of output modes to spit out query results in different formats:
.mode MODE ?TABLE? Set output mode where MODE is one of:
csv Comma-separated values
column Left-aligned columns. (See .width)
html HTML <table> code
insert SQL insert statements for TABLE
line One value per line
list Values delimited by .separator string
tabs Tab-separated values
tcl TCL list elementsBy specifying .mode insert one can get nicely formatted insert statements that can be imported right into MySQL. This is what I did to convert my Voicemail app to MySQL. However, if you don’t specify a table name on the same line, the resulting insert statements just say “insert into table”. One must use .mode insert voicemails to get insert statements out of sqlite3 that read “insert into voicemails”. A bit silly if you ask me… one would think the table name in the insert statements would just default to the name of the table you were selecting from. But, this worked great for me and was all I needed to get converted.
Voicemail integration with Highrise 2
I’ve often had trouble keeping track of my voicemail messages. Even though they get emailed to me, the emails don’t have any info about who the messages are from and I have no way of keeping track of if I’ve responded or if there’s an action item.
So I wrote a simple little Rails app to help me integrate my voicemail message into Highrise, the 37signals product which I’ve been trying, and liking, in recent weeks. Their provided REST web service API and accompanying Ruby wrapper made the whole thing way too easy. I have two models:
- Person
- Voicemail
The Person model holds a cached list of the names and Highrise ID’s of the people in my Highrise account. I can update this through a simple link in the app anytime I need.
The voicemails get into the app by a simple little “pipe to program” I added on the mail server. Something like this:
curl -u username:password --data-binary @- http://address.of.app/importWhen an email message is received at the voicemail alias, the entire email is POSTed to the address above where it’s consumed with a tiny controller action like like:
Voicemail.import(request.raw_post)The ‘import’ class method simply uses TMail to parse the message, pull off the attached WAV file, save it to the file system, and create a new Voicemail record.
The rest of the interface is simple CRUD stuff: A list of new voicemails that have come in with a link to delete and a link to save for each one. When I ‘save’ it, I choose a Person from a drop down of all my Highrise contacts and enter a very short 1 line description of what they called about. A note is instantly posted to the Person’s Highrise history with the time of the voicemail, the 1-line description, and a link to listen to the voicemail. If 37signals provided file upload capability through the API, I might just upload the file to Highrise. Or I might not since the WAV’s would eat up my storage space.
I hope to expand this a bit in the near future with a nice interface—perhaps autocomplete instead of a drop down for choosing the Person. And I think I’ll add a way to optionally create a Task in Highrise related to the Note. It would be nice if Highrise color-coded the categories applied to tasks; that way, I could categorize all the voicemail follow-up tasks and color code them so they stood out in my task list. I’ll have to submit that as a feature request.
Update
Here’s a screenshot, per Jason’s request. Click for a full sized version. As you can see, the interface is very modest.

- I’ve linked the person’s name to their Highrise page
- The little note icon on the left takes you to the note in Highrise that was created for this voicemail
Older posts: 1 2
