8.3.10 Creating a Perl Module From a CGI Program

8.3.10  Creating a Perl Module From a CGI Program

    It is possible for a program to create another program. This is not an unusual behavior when we deal with artificial intelligence (AI) type programs. Computational learning is one of the cornerstones of AI. Some approaches to computational learning create programs or functions on the fly. We are not so ambitious here. We discuss a Perl CGI program that creates a Perl module that consists of only variable declarations and assignments. A CGI program such as this can be used to install a complex product that works on platforms such as Unix or Windows. An HTML form can ask a limited number of configuration-related questions and then assign values to variables based on the answers. Filling up
the form with values correct for a particular computer system is one of the steps in the installation.

  The HTML page discussed here configures a program called NewSense. It is a sophisticated program that collects news reports from various on-line sources, automatically classifies items into categories such as political, entertainment and sports, removes duplicates or very similar stories, and presents a personalized newspaper to every individual reader of a Web site. Newsense is a trademark of Personalogy, Inc., of Colorado Springs, Colorado. What we present here is a Web page and its associated CGI program that help install NewSense at a specific site such as an on-line newspaper. The personalization process in the actual program involves AI-based computational learning built after
an analysis of the content of stories read by an individual. There is no need for the individual to provide any details of his or her likes or dislikes in terms of a questionnaire. We do not intend to discuss the details of the NewSense program. The program discussed here is similar to one initially used when NewSense was being tested, before its first release. Aspects of the real program have been removed or simplified for purposes of presentation in a book.

The person who is about to install the program on a certain computer system is shown the HTML from shown in Figure 8.13. The questions need to be answered by filling in text in input boxes. Default answers are provided for some of the questions.

 The actual HTML code for the form contains JavaScript scripts for data validation that can be performed on the browser, before the from data is transported to the server. The use of a Web page, if accompanied with proper precautionary measures, can make remote installation and update of the program over the Web possible. The FORM tag used in the HTML code is the following.

 

<FORM METHOD="GET"

 ACTION=

   "http://pikespeak.uccs.edu/cgi-bin/kalita/personalogy/basic_configure.pl">

 

It can also be written as the following if we intend to fill the form on the same machine on which the NewSense system is to be installed.

 

<FORM METHOD="GET"

     ACTION="http://localhost/cgi-bin/kalita/personalogy/basic_configure.pl">

 

The form has several fields. It is not important to know what the fields are. The CGI program that handles the form is at

http://pikespeak.uccs.edu/cgi-bin/kalita/personalogy/basic_configure.pl. The Web page shown in Figure 8.13 is located at

http://pikespeak.uccs.edu/~kalita/personalogy/basic_configure.pl.

The program is fairly simple.

 

Figure 8.13:  Questions Asked to Configure a Program

 Program 8.11

#!/usr/bin/perl -Tw
#basic_config.pl

use CGI qw(:standard);
use CGI::Carp qw(fatalsToBrowser);
use Untaint;
use strict;

##########
$CGI::POST_MAX = 1024; #max 1024 bytes posts
$CGI::DISABLE_UPLOADS = 1; 

my $configFileName = "AP_basic_config.pm";

print "Content-type: text/html\n\n";

my $webServerAbsPath = param ("WebServerLocation");
$webServerAbsPath = untaint (qr{^[a-zA-Z_0-9.-/]+$}, $webServerAbsPath);
my $cgiRoot = param ("CGIRoot");
$cgiRoot =  untaint (qr{^[\w\d/.-]+$}, $cgiRoot);
my $htmlRoot = param ("HTMLRoot");
$htmlRoot = untaint (qr{^[\w\d.-/]+$}, $htmlRoot);
my $perlSourceInstallAbsPath = param ("PerlSourceInstallDirectory");
$perlSourceInstallAbsPath = untaint (qr{^[\w\d.-/]+$}, $perlSourceInstallAbsPath);
my $perlSiteModuleAbsPath = param ("PerlSiteModuleDirectory");
$perlSiteModuleAbsPath = untaint (qr{^[\w\d-/.]+$}, $perlSiteModuleAbsPath);
my $distributionTarFileName = param ("DistributionTarFileName");
$distributionTarFileName = untaint (qr{^[\w\d-/.]+$}, $distributionTarFileName);

my $cgiAbsPath = "$webServerAbsPath/$cgiRoot";
$cgiAbsPath = untaint (qr{^[\w\d-/.]+$}, $cgiAbsPath);
my $htmlAbsPath = "$webServerAbsPath/$htmlRoot";
$htmlAbsPath = untaint (qr{^[\w\d-/]+$}, $htmlAbsPath);

print "\nPreliminary Configuration of Newsense complete!\n";
print "\n";
print "

Configuration of Newsense: Step 1 successful!

"; print < This is what you entered. If any of it is not what you want, click on the Back button of the browser, make the correction, and submit the form again.

ALL print < Question Asked Your answer Web Server Location $webServerAbsPath CGI Root $cgiAbsPath HTML Root $htmlAbsPath Perl Source Install Directory $perlSourceInstallAbsPath Perl Site Module Directory $perlSiteModuleAbsPath Distribution Tar File Name $distributionTarFileName ALL print < Recheck your responses before proceeding!

ALL print q{ Proceed to Step 2: Bring up the configure.html file on your localhost in NewSense HTML directory and answer the questions
; }; #NO MORE PRINTING TO THE WEB BROWSER open OUT, ">$perlSiteModuleAbsPath/$configFileName" or warn "Cannot open file $perlSiteModuleAbsPath/$configFileName : $!"; my $time = localtime (); print OUT q{ package AP_basic_config; #Created by:} . "$0\n" . q{#Creation date:} . "$time\n" . q{#Define all basic site-specific global variables to make preparation to install #This file is created by a CGI program use strict; use vars qw($webServerAbsPath $cgiAbsPath $htmlAbsPath ); use vars qw($perlSourceInstallAbsPath $perlSiteModuleAbsPath); use vars qw($distributionTarFileName); }; #This needs to be changed if the HTML file is changed to allow more choices print OUT q{$webServerAbsPath = "} . $webServerAbsPath . q{"} . ";\n"; print OUT q{$cgiAbsPath = "} . $cgiAbsPath . q{"} . ";\n"; print OUT q{$htmlAbsPath = "} . $htmlAbsPath . q{"} . ";\n"; print OUT q{$perlSourceInstallAbsPath = "} . $perlSourceInstallAbsPath . q{"} . ";\n"; print OUT q{$perlSiteModuleAbsPath = "} . $perlSiteModuleAbsPath . q{"} . ";\n"; print OUT q{$distributionTarFileName = "} . $distributionTarFileName . q{"} . ";\n"; print OUT "\n\n1;"; close OUT;

The initial part of the program captures the parameters that the HTML form sends to the Web server. It is quite likely that the browser and the server are running on the same machine unless remote installation is being attempted.

Next, the program creates an HTML page in the form of a table that echoes the values that the individual performing the installation is able to see for purposes of verification. As usual, one or more HTTP headers are first printed to standard output, and then, the actual HTML page. Anything printed to standard output after the HTTP headers is displayed by the browser. The response Web page for the interaction is shown in Figure 8.14.

 

Figure 8.14:  Response to Questions Asked to Configure a Program

After this, the program writes to a file the details provided by the user. The program creates a simple Perl module with the values filled by the individual performing the installation. The variables created by the program have names that have been selected by the programmer. The module created is called AP_basic_config and is stored in a file called AP_basic_config.pm.

   The module contains declarations of variables that can be seen by other programs. A variable declared with my is visible only within the current program. A variable declared with use vars can be seen by programs that are contained in other files as well. There are some limitations to what var use can do as regards to making the variable completely available outside the file, but it is acceptable in most situations. Such declarations are usually made in writing Perl modules. The module created also contains statements where
the variables declared earlier are assigned values based on the answers provided on the Web page. The module written out by the program to the file AP_basic_config.pm is given below.

 Program 8.12

package AP_basic_config;

#Created by:/var/www/cgi-bin/kalita/personalogy/basic_config.pl
#Creation date:Mon Jun 25 16:26:11 2001
#Define all basic site-specific global variables to make preparation to insta
ll
#This file is created by a CGI program

use strict;
use vars qw($webServerAbsPath $cgiAbsPath $htmlAbsPath );
use vars qw($perlSourceInstallAbsPath $perlSiteModuleAbsPath); 
use vars qw($distributionTarFileName);
$webServerAbsPath = "/var/www";
$cgiAbsPath = "/var/www/cgi-bin/personalogy";
$htmlAbsPath = "/var/www/html/personalogy";
$perlSourceInstallAbsPath = "/home/Project";
$perlSiteModuleAbsPath = "/home/kalita/public_html/personalogy";
$distributionTarFileName = "NewSense.tar";


1;

Note that it is a very simple module and contains only variable declarations and assignments. It does not contain any other statements or subroutines. This module AP_basic_config can be used by the NewSense program to be installed. The NewSense program is written as a large number of Perl modules. Some of these modules use the module AP_basic_config. A Perl module has to have a statement containing 1; at the very end.