A Perl script catalogs books and CDs with the help of barcodes

Off to the Base

The upcscan program uses the CPAN Rose::DB database wrapper to identify the database schema and insert new records into the articles table (Figure 6). Line 23 identifies the database file articles.dat in the current directory as an SQLite database, and the subsequent AutoCommit and RaiseError options ensure that new entries are written to the database without an explicit commit command and that any error that occurs immediately throws an exception.

The make_classes() method in line 27 imports the database objects into the script code, and because of this, I can simply say Article->new() later on to prepare a new entry in the articles database table.

Widgets in the POE Flow

The graphical interface is running in the main window, $top, which line 29 accepts from the $poe_main_window variable, which is exported from POE. The GUI's event loop is not left to its own devices in the script but needs to cooperates with POE's kernel.

If use Tk appears before use POE in the code, POE knows that it has to prepare an event loop for the Tk GUI; it initializes the main window and creates a pointer to it in $poe_main_window.

The configure() command in line 30 stores the UPC Reader title string in the window header and sets the background color for the GUI to #a2b2a3 (light olive green).

At the top of the window, you can see the entry widget $entry, which accepts sequences of numbers from the scanner and stores them in the global variable $UPC_VAR. Farther down is a photo widget for the book and CD covers; for organizational reasons, it is embedded in a label widget. Four Label-type widgets follow that store the title ($PRODUCT), the author/artist ($BYWHO), the scanned UPC or EAN code ($UPC), and a status message ($FOOTER).

The for loop in line 50ff. drops the widgets, top down, into the main window and calls -fill => "x" and -expand => 1 to ensure that the labels fill the horizontal space up to the border and automatically scale when the main window is expanded.

The bind() command in line 56 plays an important role. The entry widget ignores the Return character sent by the scanner because the input field is a single-line field. The bind method binds the Return key's keyboard code to the scan_done() function defined in line 68ff. to trigger processing of the code read in by the scanner.

First, the photo object's blank() method is called to remove the previous cover image. Then the title and author/artist names are replaced with blank strings. A "Processing …" message appears in $FOOTER, and the request is sent to Amazon by calling amzn_fetch(). To get ready for the next scan, line 78 immediately deletes the code read by the scanner from the entry widget. The barcode for the current product is stored in the $UPC widget.

After completing these preparations, line 58 defines a POE session, and line 65 launches the POE kernel, which controls the program from this point on until it is terminated. The POE kernel accepts user input, mouse clicks, or keyboard/scanner input and makes sure that a time slot is assigned to each handler triggered by an event. POE is very strict with the sessions it controls. If they do not have a task to complete, they are eliminated. POE does not understand that a Tk application might just be waiting for user input. To prevent it from killing the GUI, lines 58 through 63 define a session that jumps to the _start event every 60 seconds.

Ask Amazon

Once the scanner has returned a UPC or EAN code, the amzn_fetch() function in line 82ff. creates an instance of a Net::Amazon object and passes in both the developer token (you will need to apply to Amazon if you do not have one yet – see the "Installation" section below), and the global special agent LWP::UserAgent::POE, which not only retrieves web requests, like its base class LWP::UserAgent, but also collaborates with POE.

A Net::Amazon::Request::UPC-type request object talks to the Amazon web service that provides the UPC/EAN lookup facility. The request must state up front whether it wants to search for the UPC/EAN code in the Books, Music, or DVD sections.

Because the scanner does not know whether it is scanning a book or a CD, the for loop that begins in line 93 simply tries all three supported sections and terminates as soon as Amazon reports a successful search. The response returned here offers the is_success() method, which tells you whether a matching code has been found.

The amzn_fetch() function returns three parameters: the response object $resp, the section in which the match was found (Books, Music, or DVD), and the scanned UPC/EAN code.

The resp_process() function defined in line 114ff. grabs the results and uses it to update the GUI fields. The ImageUrlMedium() method for the retrieved article in $property includes a URL for a medium-sized JPEG image on Amazon's server depicting the product cover.

Buy this article as PDF

Express-Checkout as PDF
Price $2.95
(incl. VAT)

Buy Linux Magazine

Get it on Google Play

US / Canada

Get it on Google Play

UK / Australia

Related content

  • Barcode

    Machine-readable codes aren’t just for big companies anymore. With the right programs and some low-cost hardware, you can create and read the most important codes.

  • Thinking in Black and White

    Zint converts text, contact data, URLs, WiFi access credentials, and more into easily distributable barcodes or QR codes at the push of a button.

  • Perl: Network Monitoring

    To discover possibly undesirable arrivals and departures on their networks, a Perl daemon periodically stores the data from Nmap scans and passes them on to Nagios via a built-in web interface.

  • Machine Language

    The electronic brain behind ChatGPT from OpenAI is amazingly capable when it comes to chatting with human partners. Mike Schilli picked up an API token and has set about coding some small practical applications.

  • Alexandria Library Manager

    As your book collection grows, you might lose track of your volumes. Alexandria lets you catalog your tomes quickly and easily without a pesky database server.

comments powered by Disqus