Starting today, patrons who have items on hold at select branches will notice something new about the material they receive: a sticky note.
The whole point of these new stickers is to ease the work created by an ever-increasing volume of holds being placed on AADL material. Our processors have been bearing the brunt of increased loads, partly due to general growth, but also because it is so easy to place a hold online now that the number of holds we get has shot up. Now, as far as the processors are concerned, when they scan material that has been routed to the correct pickup location, a custom label, replete with patron information and barcode will spit right out of a networked label printer. This removes a step or two from the process and has led to some very happy circulation staff. Though I'm quite pleased with the way the labels turned out, what pleases me the most (besides the happy processors) is what happens behind the scenes.
What's fun about this are the relatively simple back-end components that make this work.
The III circulation client can be configured to send a print job to an email address instead of a standard receipt or line printer. In this case, I've set up an instance of Exim running on a Linux box with an address alias that pipes the email through a very simple PHP script. The PHP script parses the email, creates a PNG on the fly, then sends it to the label printer via cupsys lp.
I've been having a lot of fun with PHP's GD module lately and this little project really underscores how slick it can be. In addition to GD, I also made use of PEAR's Image::Barcode class so that the item's barcode could be included on the tag. Because PEAR's barcode class doesn't allow you to return the image as an object, I had to instantiate it as a separate script. That's fine because you can just point imagecreatefrompng to the URL. The barcode script couldn't be simpler. Not only that, it's so generic, you can really use it for all your barcoding needs:
// bcode.php if (!$_GET[input]) { return; } require_once('Image/Barcode.php'); $bcode = new Image_Barcode; $bcode->draw($_GET[input], 'int25', 'png');
'Eh? What a great class! Here's the guts of the label code--messy, I know, but it works. As you can see, it's utilizing PHP's CLI or CGI build. Yes, PHP makes a great shell scripting language too!
#!/usr/bin/php5 -q putenv('GDFONTPATH=' . realpath('/usr/local/php/fpdf/ttf/')); // Where my TTF fonts are $fd = fopen("php://stdin", "r"); $email = ""; while (!feof($fd)) { $email .= fread($fd, 1024); } fclose($fd); $item = hold_item_info($email); $x = 350; $y = 350; $daysonshelf = 8; $unique = time() . rand(2000000, 6000000); $font = 'arialbd'; $logourl = "http://www.aadl.org/staticimages/aadllogo.gif"; $bcodeurl = "http://bcodeserver.aadl.org/bcode.php?input=$item[barcode]"; // Create the image $im = imagecreatetruecolor($x, $y); $im2 = imagecreatefrompng($bcodeurl); $im3 = imagecreatefromgif($logourl); $white = imagecolorallocate($im, 255, 255, 255); $black = imagecolorallocate($im, 0, 0, 0); imagefill($im, 0, 0, $$white); imagefilledrectangle($im, 0, 0, $x, $y, $white); $spine_name = $item[plname]; if ($item[pfname]) { $spine_name .= ', ' . strtoupper($item[pfname]{1}) . '.'; } $holdtil = (time() + ($daysonshelf * 86400)); $holdtilfmt = date("n/j", $holdtil); $canceldate = date("m-d-Y", $holdtil); $details = 'Title: ' . $item[title] . "\n" . 'Author: ' . $item[author] . "\n" . 'Callnum: ' . $item[callnum] . "\n" . 'Barcode: ' . $item[barcode] . "\n" . 'Held for: ' . $item[plname] . ', ' . $item[pfname] . "\n" . 'Pickup location: ' . $item[pickuploc] . "\n" . 'Hold until: ' . $canceldate; imagettftext($im, 28, 270, 40, 20, $black, $font, $spine_name); imagefilledrectangle($im, 72, 20, 74, 345, $black); imagefilledrectangle($im, 15, 300, 70, 335, $white); imagettftext($im, 12, 0, 32, 320, $black, $font, $holdtilfmt); ImageCopyMerge($im , $im2, 85, 40, 0, 0, ImageSX($im2), ImageSY($im2), 100); ImageCopyMerge($im , $im3, 85, 275, 0, 0, ImageSX($im3), ImageSY($im3), 100); imagettftext($im, 12, 0, 85, 120, $black, $font, $details); imagepng($im,"/tmp/pic$unique.png"); imagedestroy($im); if ($item[printer]) { $printer = $item[printer]; exec("/usr/bin/lp -d $printer /tmp/pic$unique.png"); } unlink("/tmp/pic$unique.png"); // Functions Below function hold_item_info($email) { // This function returns the $item array -- customize it for your environment. }
The script creates a PNG that looks something like this:

The PNG is sent to the Zebra S4M and printed on a label that has Post-It-like adhesive. Processors then peel off the backing and fold the sticker over the spine of the book and put it on the hold shelf.
The hardest part of this whole project was getting the printer to work with CUPS. I wound up bastardizing some existing postscript drivers through trial and error. As you can see from the photos, I still don't have it right. I'd like the image to take up the entire sticker area. All in good time. If anyone out there wants the driver I'll be glad to email it--maybe you can get it working better! Just ask.
[update]
This is how the labels are affixed to material:

You can overlook the fact that the label info doesn't match the book info--it's just for show!
[/update]
[tags]library, libraries, PHP, coding[/tags]














7 Comments so far
Leave a comment
Ok, that’s totally neat! I do have a question/suggestion though. Do apply stickers to your hold books? If yes, woohoo! everything is dandy.
If no, may I suggest that you print the name in the opposite direction (mirror of what you have now)? That way you can slip it in the book and the name is displayed nicely at the top.
By maire on 03.17.06 9:43 am | Permalink
Yes, the stickers are applied directly to the books and the vertical name is displayed on the spine so that circ staff can see it easily on the shelf.
By john on 03.17.06 9:47 am | Permalink
makes sense now. thank you!
We, if you haven’t guessed, do the paper in the top of the book thing. It works well for most items.
By maire on 03.17.06 3:05 pm | Permalink
Do the stickers peel off at some point? I might not be getting it, but it seems odd to have a patron’s name permanently affixed to the outside of a book.
By Edward Vielmetti on 03.17.06 3:22 pm | Permalink
They have post-it-like adhesive that peels of very easily.
By john on 03.17.06 4:18 pm | Permalink
Also, a big point of this process is that we do self-pickup of holds at Malletts Creek Branch, and we will at Pittsfield too. The labels will actually be placed around the opposite edge of the book, with the spines facing in when they’re shelved for self-pickup. They’re intended to be peeled off and thrown away by the patron.
By Eli on 03.18.06 1:00 am | Permalink
John, can you tell me the name of the brand and your source for the stickers you are using for this?
Thanks, Chip
c.kruthoffer@lanepl.org
(We’ve had receipt printers for years, but still tape the ends of the receipts down for this. Stickers make more sense.)
By Chip on 03.20.06 11:19 am | Permalink
Leave a comment
Line and paragraph breaks automatic, e-mail address never displayed, HTML allowed:
<a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>