Press "Enter" to skip to content

Month: June 2013

Delicious Library 3

Delicious Library 3 WebsiteMy wife and I read a lot of books. Now that our son has gotten a little older and needs less attention, I go through more than a book a week on average, Bobbie doesn’t go through as many books in number, but she is reading much larger non-fiction books and taking copious amounts of notes.

Many years ago I bought Delicious Library 2 (DL2) as a part of a bundle deal. Bobbie and I used it to catalog all of our fiction and collectable books. It worked well enough and with some simple PHP and YUI coding I built a simple web page we could use on our phones to check our library while out and about.

Then disaster struck, I reformatted/re-installed all of our computers and updated them to the latest version of the Mac OS. I thought I had backed everything up, but apparently Delicious Library’s database was not.

Lately Bobbie has been asking me about how to update the Library page with the new books we have purchased. I did another round of research for library software and came to the decision to buy and use Delicious Library 3 (DL3).

I bought it from the Apple App Store, which means it can run on all of our machines and it will stay up-to-date via the App Store app.

The great news is that even though I had lost the DL2 database, DL3 was able to import the CSV file I was using on our website and retrieve the information for the 450+ plus books that were in it from Amazon. That was pretty amazing and made me very happy.

Also, the iPhone app Delicious Scanner worked great for me successfully scanning about 75% of the books that had barcodes in our library. I was kind of surprised how well it worked, DL2 was not nearly as successful using the iSight camera on a laptop. I was also surprised by how many books we have that do not have any kind of bar code or even an ISBN code, a lot of Bobbie’s antique books predate ISBN.

The good news is that scanning the rest of the books went faster than I expected and DL3 did a good job of finding the books on Amazon with a little bit of manual help. DL3 is not fully automatic; I don’t think any book library app could be, there is always going to be manual work involved. Adding the meta-data that is important to us like the name of the Series that a book is a part of, the book’s number in the series, and the character name’s that appear in the book is always going to be manual because what is important to us is not going to be important to everyone.

The bad news is the DL3 is still burying its database in a proprietary format in a deeply hidden corner of your computer. There is still no way for multiple people to collaborate on a single library, you can export/import libraries but it is very klunky and if every book does not have an associated ISBN or Amazon code you are bound to have duplicate entries. And the templates for exporting an HTML version of your library are absolutely useless!

The HTML output and even the default interface of DL3 makes me very sad and frustrated. The developers/designers of the app spent all this time on graphics, 3D effects, and a multitude of wood grains instead of on the usability of the app.

This is what we need from a library app:

  1. Easy book entry
  2. Easy to find a book in the library

Delicious Library 3 is awesome at book entry, that part fits my needs almost perfectly. The only thing that would make it better is integration with data sources other than Amazon.

DL3 Bookshelf ViewWhen it comes to finding a previously entered book, the DL3 app on the desktop works ok. The default 3D Bookshelf view with the books on a shelf (duh) is absolutely worthless for this, it makes it almost impossible to scan through the books and the cover from Amazon may not match the cover of the real book on your shelf making it counter-productive.

Switching to List view improves the situation a lot. You can control what fields/columns are visible and sort the columns.

DL3 Search ResultsOh wait; right there in the top left is search box. Well that should help right? WRONG, when you enter text in that box it displays the results in a pop-up with a fixed width that truncates the book titles to the point that they are useless.

I am going to stop complaining right there. Delicious Library has a lot of usability issues that will apparently never be addressed, lets move on to why it is still a very useful app.

You can output a CSV file!

DL3 Export a CSVI have written a little PHP file that takes the CVS file that DL3 outputs and makes a very simple HTML table with the data. Then I use jQuery and a couple libraries to make the table sortable, searchable, and filterable.

The PHP is not very efficient, if we had many more books the JavaScript/jQuery would be to slow to be useful, and having it all in a database would make it easier to do some other cool stuff with the data. But for now the simple PHP and JavaScript fit our needs and give us a great interface into our book library.

My Simple Library
My Simple Library

Here is my UGLY PHP:

$firstRow = true;
$file_handle = fopen("export.csv""r");
while (!feof($file_handle) ) {
    $line_of_text = fgetcsv($file_handle1024);
    $author = $line_of_text[1];
    $title = $line_of_text[4];
    $series = $line_of_text[2];
    $subtitle = $line_of_text[3];
    if ($author == "") {
        $author = " ";
    if ($title == "") {
        $title = " ";
    if ($series == "") {
        $series = " ";
    if ($subtitle == "") {
        $subtitle = " ";
    if ($firstRow == false) {
        if ($line_of_text[0]) {
            print "" . $author . "" . $title . "" . $series . "" . $subtitle . " ";
    } else {
        $firstRow = false;

I am using jQuery 2.0.2 and tablesorter with the Zebra and Filter widgets.

Here is the JavaScript, it is almost entirely cut and paste from the tablesorter web page:

          theme : 'blue',
          sortList: [[0,0], [1,0]],
          widgets: ["zebra""filter"],
          widgetOptions : {
            // If there are child rows in the table (rows with class name from "cssChildRow" option)
            // and this option is true and a match is found anywhere in the child row, then it will make that row
            // visible; default is false
            filter_childRows : false,

            // if true, a filter will be added to the top of each table column;
            // disabled by using -> headers: { 1: { filter: false } } OR add class="filter-false"
            // if you set this to false, make sure you perform a search using the second method below
            filter_columnFilters : true,

            // css class applied to the table row containing the filters & the inputs within that row
            filter_cssFilter : 'tablesorter-filter',

            // class added to filtered rows (rows that are not showing); needed by pager plugin
            filter_filteredRow   : 'filtered',

            // add custom filter elements to the filter row
            // see the filter formatter demos for more specifics
            filter_formatter : null,

            // add custom filter functions using this option
            // see the filter widget custom demo for more specifics on how to use this option
            filter_functions : null,

            // if true, filters are collapsed initially, but can be revealed by hovering over the grey bar immediately
            // below the header row. Additionally, tabbing through the document will open the filter row when an input gets focus
            filter_hideFilters : false// true, (see note in the options section above)

            // Set this option to false to make the searches case sensitive
            filter_ignoreCase : true,

            // if true, search column content while the user types (with a delay)
            filter_liveSearch : true,

            // jQuery selector string of an element used to reset the filters
            filter_reset : 'button.reset',

            // Delay in milliseconds before the filter widget starts searching; This option prevents searching for
            // every character while typing and should make searching large tables faster.
            filter_searchDelay : 300,

            // if true, server-side filtering should be performed because client-side filtering will be disabled, but
            // the ui and events will still be used.

            // Set this option to true to use the filter to find text from the start of the column
            // So typing in "a" will find "albert" but not "frank", both have a's; default is false
            filter_startsWith : false,

            // Filter using parsed content for ALL columns
            // be careful on using this on date columns as the date is parsed and stored as time in seconds
            filter_useParsedData : false,

            filter_onlyAvail : 'filter-onlyAvail'

If you are looking for a way to keep track of your books, give Delicious Library 3 a try. So far it is working well for us.


The Hunter by Richard Stark

I bought this audiobook from Audible and listened to it using the Audible app on my iPhone.

I enjoyed the movie Payback with Mel Gibson, even though I think John Myhre ruined the theatrical release, which got me interested in reading the book that it was based on. This is that book. But before reading this book, forget the theatrical release of the movie entirely.

This is a dark book with a lead character that is not likeable in any way. I suspect there are plenty of people out in the world that would like to think of themselves as being a lot like Parker, hard, mean, uncaring and as tough as nails. But if they are like Parker they do not have any friends and will lead a very lonely and hard life.

I enjoyed this book but it did not make me want to read the rest of the 25 books in the series. Yes, you read that right, there are currently 25 books in the series, so obviously someone likes them a lot.

John Chancer does an amazing job narrating this book, he gives Parker a hard edge delivering his lines in a flat emotionless way that makes him very believable.

You’ll have to excuse me now, I am going to go watch "Payback: Straight Up: The Director’s Cut" which is much closer to the original story than the theatrical release.

From the publisher:

You probably haven’t noticed them. But they’ve noticed you. They notice everything. That’s their job. Sitting quietly in a nondescript car outside a bank making note of the tellers’ work habits. Lagging a few car lengths behind the Brinks truck on its daily rounds. Surreptitiously jiggling the handle of an unmarked service door at the racetrack. They’re heisters. They’re pros, and Parker is far and away the best of them. Tough, smart, hardworking, and relentlessly focused on his trade, he is the heister’s heister, the robber’s robber, the heavy’s heavy. You don’t want to cross him, and you don’t want to get in his way, because he’ll stop at nothing to get what he’s after.

In The Hunter, the first volume in the series, Parker roars into New York City, seeking revenge on the woman who betrayed him and on the man who took his money, stealing and scamming his way to redemption.

©1962 Richard Stark (P)2010 AudioGO

I rate this book an 8 out of 10 and recommend it to anyone who enjoys crime novels or felt disappointed by the theatrical release of Payback.


Scoundrels: Star Wars by Timothy Zahn

I bought this audiobook from Audible and listened to it using the Audible app on my iPhone.

I bought this book based on reviews at Audible and my love of Star Wars. As a kid I read the novelizations and Alan Dean Foster’s Splinter of the Mind’s Eye, which were all great.

Timothy Zhan does a good job of adding depth to the Star Wars universe and giving us a little more insight into the relationships between Han, Chewbacca, and Lando.

Marc Thompson does a great job with the narration. He gives Han a voice that is about half way between Harrison Ford and Patrick Warburton as The Tick. I really like it.

Overall it is not a very "Epic" story, it is more of a peek into the lives of Han, Chewbacca and Lando. It is limited by the Star Wars canon and does a very good job within those limitations.

From the publisher:

To make his biggest score, Han’s ready to take even bigger risks.

But even he can’t do this job solo.

Han Solo should be basking in his moment of glory. After all, the cocky smuggler and captain of the Millennium Falcon just played a key role in the daring raid that destroyed the Death Star and landed the first serious blow to the Empire in its war against the Rebel Alliance. But after losing the reward his heroics earned him, Han’s got nothing to celebrate. Especially since he’s deep in debt to the ruthless crime lord Jabba the Hutt. There’s a bounty on Han’s head – and if he can’t cough up the credits, he’ll surely pay with his hide. The only thing that can save him is a king’s ransom. Or maybe a gangster’s fortune?

That’s what a mysterious stranger is offering in exchange for Han’s less-than-legal help with a riskier-than-usual caper. The payoff will be more than enough for Han to settle up with Jabba – and ensure he never has to haggle with the Hutts again.

All he has to do is infiltrate the ultra-fortified stronghold of a Black Sun crime syndicate underboss and crack the galaxy’s most notoriously impregnable safe. It sounds like a job for miracle workers…or madmen. So Han assembles a gallery of rogues who are a little of both – including his indispensable sidekick Chewbacca and the cunning Lando Calrissian. If anyone can dodge, deceive, and defeat heavily armed thugs, killer droids, and Imperial agents alike – and pull off the heist of the century – it’s Solo’s scoundrels. But will their crime really pay, or will it cost them the ultimate price?

©2012 Timothy Zahn (P)2012 Random House Audio

I rate this book an 8 out of 10 and recommend it to anyone who loves the Star Wars universe.


Rip-Off!: A Collection of Short Stories

I bought this audiobook from Audible and listened to it using the Audible app on my iPhone.

This book was fun, there are a couple of stand-out stories here, but overall it didn’t really wow me.

It is definitely worth listening to if you have any favorite authors with stories in it.

From the publisher:

In Rip-Off!, 13 of today’s best and most honored writers of speculative fiction face a challenge even they would be hard-pressed to conceive: Pick your favorite opening line from a classic piece of fiction (or even non-fiction) – then use it as the first sentence of an entirely original short story.

In the world of Rip-Off!, "Call me Ishmael" introduces a tough-as-nails private eye – who carries a harpoon; The Wonderful Wizard of Oz inspires the tale of an aging female astronaut who’s being treated by a doctor named Dorothy Gale; and Huckleberry Finn leads to a wild ride with a foul-mouthed riverboat captain who plies the waters of Hell.

Once you listen to Rip-Off! you’ll agree: If Shakespeare or Dickens were alive today, they’d be ripping off the authors in this great collection.

The stories included in Rip-Off! are:

  • "Fireborn" by Robert Charles Wilson
  • "The Evening Line" by Mike Resnick
  • "No Decent Patrimony" by Elizabeth Bear
  • "The Big Whale" by Allen M. Steele
  • "Begone" by Daryl Gregory
  • "The Red Menace" by Lavie Tidhar
  • "Muse of Fire" by John Scalzi
  • "Writer’s Block" by Nancy Kress
  • "Highland Reel" by Jack Campbell
  • "Karin Coxswain" or "Death as She Is Truly Lived" by Paul Di Filippo
  • "The Lady Astronaut of Mars" by Mary Robinette Kowal
  • "Every Fuzzy Beast of the Earth, Every Pink Fowl of the Air" by Tad Williams
  • "Declaration" by James Patrick Kelly

As a bonus, the authors introduce their stories, explaining what they ripped-off – and why.

Rip-Off! was produced in partnership with SFWA – Science Fiction & Fantasy Writers of America. Gardner Dozois served as project editor.

For more books from the authors of Rip-Off! click here.

©2012 Science Fiction and Fantasy Writers of America, Inc. (P)2012 Audible, Inc.

I rate this book a 7 out of 10, a couple of the stories were very nice but most of them were just OK.


Maintainable JavaScript by Nicholas C. Zakas

Maintainable JavaScript by Nicholas C. Zakas
Maintainable JavaScript by Nicholas C. Zakas
I read this book using Safari Books Online using various laptops and an iPad.

This is an amazing book.

Following a style guide while programming is common in many languages, but for me it is a new idea in JavaScript. Reading Douglas Crockford’s Style Guide can teach you a lot, but Maintainable JavaScript teaches you not only the how, but also the why.

This book does focus on following a style guide but it also includes how to set-up and use a build system with your JavaScript. I can’t wait to start putting that information to use. As a front-end developer I have not used a build system.

Nicholas also has a great presentation available that covers many of the topics in the book on SlideShare at

From the publisher:

You may have definite ideas about writing code when working alone, but team development requires that everyone use the same approach. With the JavaScript practices in this book—including code style, programming tips, and automation—you’ll learn how to write maintainable code that other team members can easily understand, adapt, and extend. Author Nicholas Zakas assembled this collection of best practices as a front-end tech leader at Yahoo!, after completing his own journey from solo hacker to team player.

I rate this book a 10 out of 10 and recommend it to anyone who has moved beyond beginner JavaScript.