#!/usr/bin/perl
## 'Shebangs' must be on the first line.
## On *nix use, e.g. #!/usr/bin/perl
## On Windows with Cygwin, use, e.g. #!c:/cygwin/bin/perl
=pod Notes and ToDo
Con-way XML Sample Code for Image Retrieval Interface
required software: Expat (http://sourceforge.net/projects/expat/)
To execute this as CGI in a browser, you must configure your webserver accordingly.
For example, if you are using Apache, your httpd.conf file would have something
like this:
## Add +ExecCGI to the default directory
Options FollowSymLinks +ExecCGI
AllowOverride None
## Add the handler to execute CGI scripts
AddHandler cgi-script .cgi .pl
## Create an alias and directory to point to where you have your perl scripts
## With this, you would then use the URL http://WEBROOT/perl/myScript.pl
Alias /perl "C:/workspace/eclipse/DEV_PERL"
Options Indexes MultiViews ExecCGI
AllowOverride None
Order allow,deny
Allow from all
## TODO:
* replace the USERNAME and PASSWORD String values below
with your Con-way username and password
* replace PRONUMBER strings below with your own 9-digit PRO Numbers
* update $imageDir with the location to which you want to write
* the image files on your webserver
* update $imageUrl with the URL to access the files
Send questions to Con-way XML Support at web.support@Con-way.com
=cut
use strict;
use CGI qw(:standard);
use CGI::Carp qw(warningsToBrowser fatalsToBrowser);
use HTTP::Request::Common;
use LWP::UserAgent;
use Crypt::SSLEay;
use URI::Escape;
use XML::Parser;
use XML::SimpleObject;
use MIME::Base64;
use Date::Format;
=pod
Documentation for XML::SimpleObject here:
http://aspn.activestate.com/ASPN/CodeDoc/XML-SimpleObject/SimpleObject.html
=cut
## Replace USERNAME and PASSWORD strings with your Con-way username and password
my $username = 'USERNAME';
my $password = 'PASSWORD';
my $title = 'Image Retrieval';
my $requestType = 'ImageRequest';
my $responseType = 'ImageResponse';
my $conwayUrl = 'https://www.Con-way.com/';
my $servletUri = 'webapp/imaging_app/XmlImageRetrieverServlet';
my $postUrl = $conwayUrl.$servletUri;
## TODO update $imageDir with the location to which you want to write
## the image files on your webserver
## update $imageUrl with the URL to access the files
## on Windows, like this:
my $imageDir = "C:\\Program Files\\Apache Group\\Apache2\\htdocs\\conwayImages\\";
## on OS X, like this:
# my $imageDir = "/Library/WebServer/Documents/conwayImages/";
my $imageUrl = "http://localhost/conwayImages/";
=pod XML Data setup
In actual use, you would probably populate the parameters
from data submitted via an on-line form or database.
For this sample we will just hard code some dummy data.
=cut
print header; ## Start the HTML page
my @getValues = split(/&/,$ENV{QUERY_STRING});
my %myInput = ();
foreach my $i (@getValues) {
my($label, $data) = split(/=/, $i);
$myInput{"$label"} = $data;
}
## If you don't pass data in as a GET variables, hard code them here:
## Build the XML Request --
# replace PRONUMBER with your own 9-digit PRO Number
if (! defined $myInput{'pro'} ) {
$myInput{'pro'} = 'PRONUMBER';
}
if (! defined $myInput{'type'} ) {
$myInput{'type'} = 'BL'; ## Type may be BL, DR, LOA, WI
}
if (! defined $myInput{'format'} ) {
$myInput{'format'} = 'jpeg'; ## Format may be pdf, jpeg, png, tiff
}
my $xmlRequest = "
$myInput{'pro'}
$myInput{'type'}
$myInput{'format'}
";
## URL Encode the XML String
$xmlRequest = uri_escape($xmlRequest);
## Set up the HTTP request
my $req = HTTP::Request->new(POST => $postUrl);
$req->authorization_basic($username, $password);
$req->content_type('application/x-www-form-urlencoded');
$req->content("$requestType=$xmlRequest");
my $userAgent = LWP::UserAgent->new;
my $resp = $userAgent->request($req);
## Abort now with error message if not successful
if (!$resp->is_success) {
print $resp->error_as_HTML;
exit;
}
## Parse the XML response
my $parser = XML::Parser->new(ErrorContext => 2, Style => "Tree");
my $respObj = XML::SimpleObject->new( $parser->parse($resp->content) );
my $rootEl = $respObj->child($responseType);
## Output HTML
print "
Sample Perl for Con-way XML $title>
Sample Perl Con-way XML $title
";
## check for general error (usually XML input) at child element of root
my $err = $rootEl->child("Error");
if ($err) {
print "XML Input Error: " . $err->value;
parseElement($rootEl);
print end_html;
exit;
}
## Now get the array of Image elements
my @images = $rootEl->children("Image");
## Process the array of Image(s), first checking for any error elements
my $errMessage = "";
foreach my $image (@images) {
## check for Errors
foreach my $error ($image->children("Error")) {
if ($error) {
$errMessage .= $error->value . "\n";
}
}
}
## If any errors found, display message and exit.
if ($errMessage) {
print $errMessage;
print end_html;
exit;
}
## Set up HTML form
print "\n
";
## Get unique number from Datetime
my ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst)=localtime(time);
my $uniqueString = sprintf "%02d%02d%02d_%02d%02d%02d",$year-100,$mon+1,$mday,$hour,$min,$sec;
## Process the array of Images, and output optionally to HTML page
foreach my $image (@images) {
my $pro = $image->child("PRONumber")->value;
my $type = $image->child("ImageType")->value;
my $format = $image->child("ImageFormat")->value;
my @encodedPages = $image->children("ImageData");
my $pageString = ""; ## page number for filename
my $pages = @encodedPages;
for(my $i = 0; $i < $pages; $i++) {
my $decodedPage = MIME::Base64::decode($encodedPages[$i]->value);
if ($pages > 1) {
$pageString = $i+1;
if (length($pageString) < 2) {
$pageString = '0'.$pageString;
}
$pageString = '_'.$pageString;
}
my $imageLabel = "$type image for PRO number $pro - $pageString";
my $fileName = $type.'-'.$pro.'-'.$uniqueString.$pageString.'.'.$format;
my $filePath = $imageDir.$fileName;
my $fileUrl = $imageUrl.$fileName;
open(FH, "> $filePath") or die "Cannot open $filePath for writing: $!";
## print 'Writing '.$imageLabel."\n";
print FH $decodedPage;
close(FH) or die "FH didn't close: $!";
print "
";
}
}
print end_html;
=item
This subroutine accesses and prints the XML tree for the element argument,
printing element names, attibutes and text values, but not in any order.
It processess recursively, so as to print the entire tree for the given element.
=cut
sub parseElement {
my $parseEl = $_[0];
print "Parsing element <", $parseEl->name, ">:\n";
printElementAttributes($parseEl);
printElementValue($parseEl);
foreach my $element ($parseEl->children()) {
print "<", $element->name, "> element - \n";
printElementAttributes($element);
printElementValue($element);
if ($element->children()) {
print " Beginning children of <",$element->name,">: \n\n";
parseElement($element);
print " End of children for <", $element->name, ">\n";
}
print "\n";
}
}
sub printElementAttributes {
my $element = $_[0];
if ($element->attributes()) {
my %attributes = $element->attributes();
print "\t", "Attributes: ";
foreach my $key (keys %attributes) {
my $value = $attributes{$key};
print $key."=\"".$value ."\" ";
}
print "\n";
}
}
sub printElementValue {
if ($_[0]->value) {
print "\t", "Value: ", $_[0]->value, "\n";
}
}