#!/usr/local/bin/perl -w
#
# This is an example of writing a VXML application for TellMe.com in Perl.
# I wrote this because when I walk into a book, CD or DVD store, I
# immediately forget what I own. Using my cell phone, I can call into
# 1-800-555-TELL, select the book database, enter the ISBN number, and know
# if I own it or not. I've built in some infra-structure for the CD and
# DVD portion, but at the moment it only returns a 'Not implemented
# message'. I'll prolly add this as I go on.
#
# To use it, you'll first need an account at www.TellMe.com. It's free, so
# you should go get one now. As far as setting up the TellMe side, it's
# pretty straight forward, and I don't want to explain it here, since they
# may change it. Next, put the script in your favorite directory. I put
# mine in /vxml off my docroot, and name it according to the extension it
# will be assigned to from TellMe.com. Since I have multiple extensions, it
# makes it easy to keep track of what scripts are associated with what
# extensions.
#
# You'll need to create a database (I use mySQL) with the structure that's
# at the __END__ section. It's a direct mysqldump of my Media database.
# Set the variables below to the host, database name, etc. Security says
# you should make sure that the user you allow to access the database only
# has SELECT privledges. If someone manages to dump your script source, you
# don't want a DB writable password being exposed. Don't forget to put a
# index.html file in the directory also, so it's not browsable.
#
# Odds & ends: Some ISBN numbers have an 'X' in the 10th position. Since a
# DTMF pad doesn't have 'X', we use '9'. If the script sees a '9' in the
# 10th position it will check for both an entry ending in '9' and in 'X'.
# If it finds both (and you'd be way out beyond the statistical norm if you
# did), it will read back both titles. The help could no doubt be clearer,
# but since only trained users are using it, you get what I needed as a
# reminder.
#
# Requires the following modules:
# CGI
# DBI
#
# Copyright 2001(c) J.C.Wren jcwren@jcwren.com
# A production of Twitching Monk Software
# No rights reserved, use as you see fit. I'd like to know about it, though, just for kicks.
#
# 2001/03/23 - 1.00.00 - Initial release
#
#
use strict;
use CGI;
use DBI;
use Carp;
#
# Our script name. TellMe doesn't handle not having a script name correctly.
#
use constant cScriptName => '54529.pl';
#
# Tune these for your database setup
#
use constant cDB_Host => 'localhost'; # Host for database
use constant cDB_Database => 'Media'; # Database to use
use constant cDB_Table_Books => 'Books'; # Table name
use constant cDB_User => 'media'; # User name to access DB with
use constant cDB_Pass => 'media'; # Our super-secret password (!)
#
# Action dispatch list
#
my %actionList = ('mainmenu' => \&function_mainmenu,
'books' => \&function_books,
'cds' => \&function_cds,
'dvds' => \&function_dvds,
'help' => \&function_help,
);
my %actionListBooks = ('getisbn' => \&function_books_getisbn,
'lookup' => \&function_books_lookup,
'mainmenu' => \&function_books_mainmenu,
);
#
# Help for the clueless (or me, after two days of not using it)
#
my %helpList = ('mainmenu' => qq{Say books or press 1 for the book database.
Say C dees or press 2 for the C D database.
Say D V dees or press 3 for the D V D database.
Hang up to exit system.
End of help.
},
'getisbn' => qq{Say or type the 10 digit I S B N number.
If the number has the letter X in it use 9, instead.
Say menu or press star to return to the main menu, or hang up.
End of help.
},
'unknown' => qq{Unknown help request.
},
);
#
# Main
#
{
my $cgi = new CGI;
$| = 1;
$cgi->cache (1);
my $goto = $cgi->param ('goto') || 'mainmenu';
$goto = 'mainmenu' if (!$actionList {$goto});
&{$actionList {$goto}} ($cgi);
}
#
# Main menu (doncha love redundant comments?)
#
sub function_mainmenu
{
my $cgi = shift;
write_headers ($cgi);
print <<"ENDHERE";
ENDHERE
}
#
# Book handler
#
sub function_books
{
my $cgi = shift;
my $option = $cgi->param ('option') || 'getisbn';
$option = 'getisbn' if (!$actionListBooks {$option});
&{$actionListBooks {$option}} ($cgi);
}
sub function_books_getisbn
{
my $cgi = shift;
write_headers ($cgi);
print <<"ENDHERE";
ENDHERE
}
sub function_books_lookup
{
my $cgi = shift;
my $isbn = $cgi->param ('isbn') || 0;
if (length ($isbn) != 10)
{
short_message ($cgi, "The I S B N entered was not 10 digits. Please try again.", 'books', 'getisbn');
}
elsif ($isbn =~ m/[^0-9]/)
{
short_message ($cgi, "The I S B N must be all digits. Please try again.", 'books', 'getisbn');
}
else
{
if (my $database = DBI->connect ("DBI:mysql:@{[cDB_Database]}:@{[cDB_Host]}", cDB_User, cDB_Pass))
{
my $query = qq{SELECT Title,ISBN FROM @{[cDB_Table_Books]} WHERE ISBN='$isbn'};
$query .= qq{ OR ISBN='} . substr ($isbn, 0, 9) . qq{X'} if (substr ($isbn, -1, 1) eq '9');
my $cursor = $database->prepare ($query) or internal_error ($cgi, $database->errstr);
$cursor->execute or internal_error ($cgi, $database->errstr);
my $rows = $cursor->fetchall_arrayref;
if (scalar @$rows)
{
if (scalar @$rows == 1)
{
short_message ($cgi, "I S B N present. Title is @$rows[0]->[0].", 'books', 'getisbn');
}
else
{
my $titles = "Multiple I S B N matches. Titles are ";
$titles .= $_->[0] . '1000