#!/usr/bin/perl -w
use strict;

package Handout;
use base qw/CGI::Application/;

# Perl CPAN libraries
use CGI;
use CGI::Carp qw/fatalsToBrowser/;
use CGI::Pretty qw/:html3/;
use CGI::FormBuilder;
# use Data::Dumper;			# debug only
use File::Slurp;			# easy, quick file access
use File::Basename;			# portable way to see filenames
use Pod::Usage;				# help screens are in pod format

# Application libraries
use Info;

# File::Slurp::append_file(LOG, ("ms nsrender $text\n")) if DEBUG;
use constant { 
	DEBUG => 1,
	NOBUG => 0,
	LOG   => "data/log",
};

# Globals
our $method = $ENV{REQUEST_METHOD} || 'POST';
    $method = 'GET' if DEBUG;
our $hot = 0;		# true after submitted is checked
 
# my %args = _args(@_);
# handle either ->field($name) or ->field(name => $name)
# my $name = (@_ % 2 == 0) ? '' : shift();
# my %args = _args(@_);
# $args{name} ||= $name;
sub _args (;@) {
    die "Odd number of arguments passed into ", (caller(1))[3]
        unless (@_ % 2 == 0);
    # strip off any leading '-opt'
    my @args;
    while (@_) {
        (my $k = shift) =~ s/^-//;
        push @args, $k, shift;
    }
    return @args;
}

sub setup {
    my $self = shift;

    $self->start_mode('splash');
    $self->mode_param('rm');
    $self->tmpl_path('./');
    $hot = 0;

    $self->run_modes(
			select_handout => 'select_handout',
			select_topics  => 'select_topics',
			select_info    => 'select_info',
			show_handout   => 'show_handout',
			import_handout => 'import_handout',
			splash         => 'splash',
    );
}

# Filter all screens for common look and feel
sub cgiapp_postrun {
    my ($self, $body_ref) = @_;

    # Creating common look
    my $output;

    # Look for handout output
    if ( $$body_ref =~ /\








";
	$output .= "


" . $$body_ref . "
"; } # Return by reference $$body_ref = $output; } sub splash { my $self = shift; my $text = shift || "TCM Handouts Main Menu"; my @fields = qw(); my $form = CGI::FormBuilder->new( method => $method, name => 'splash', fields => \@fields, submit => [ 'Select Handout', 'Import Handout', 'Help'], reset => 0, text => 'Select or Import a Handout', ); $form->field(name => 'rm', value => "splash", force => 1,type => 'hidden'); return $form->render( text => $text ) unless $form->submitted && ! $hot; if ( $form->submitted eq 'Select Handout' ) { return $self->select_handout(); } elsif ( $form->submitted eq 'Import Handout' ) { return $self->import_handout(); } elsif ( $form->submitted eq 'Help' ) { return $self->help(); } elsif ( $form->submitted eq 'Return' ) { $text = "Welcome back from Handout Help"; } return $form->render( text => $text ); } # Use pod for help screen sub help { my ($self) = @_; # Get the help as an html source file my $filename = $0; $filename =~ s/cgi$/pod/; my $output = `pod2html handout.pod`; # Return the source with a submit back to splash my @fields = qw(); my $form = CGI::FormBuilder->new( method => $method, name => 'Handout Help', fields => \@fields, submit => [ 'Return' ], reset => 0, text => "Handout Help", ); $form->field(name => 'rm', value => "splash", force => 1, type => 'hidden'); $output =~ s/\<\/body\>//; $output =~ s/\<\/html\>//; $output .= $form->render; $output .= ""; return $output; } sub select_handout { my $self = shift; my $text = shift || "TCM Handouts selection"; my @handouts = Info->get_all; my @fields = qw(handout_name); my $form = CGI::FormBuilder->new( method => $method, name => 'select_handout', fields => \@fields, required => [ qw(handout_name) ], values => { handout_name => $handouts[0] }, options => { handout_name => \@handouts }, submit => [ 'Select Topics', 'Main Menu', ], reset => 0, text => 'Select a handout', ); $form->field(name => 'rm', value => "select_handout",force => 1, type => 'hidden'); return $self->splash("Import a handout first") unless scalar @handouts; if ( $form->submitted eq 'Select Topics' ) { return $self->select_topics( $form->field('handout_name') ); } elsif ( $form->submitted eq 'Main Menu' ) { return $self->splash(); } return $form->render( text => $text ); } sub select_topics { my $self = shift; my $name = shift || $self->query->param('handout_name') || die "Missing handout name\n"; my $info = Info->new($name); my @fields = $info->topics; my $form = CGI::FormBuilder->new( method => $method, name => 'select_topics', fields => \@fields, submit => [ 'Select Info', 'Main Menu' ], reset => 0, text => 'Select Topics', options => $info->topic_options, ); $form->field(name => 'rm', value => "select_topics", force => 1, type => 'hidden'); $form->field(name => 'handout_name', value => $name, force => 1,type => 'hidden'); if ( $form->submitted eq 'Select Info' ) { return $self->select_info($form, 1); } elsif ( $form->submitted eq 'Main Menu' ) { return $self->splash(); } return $form->render( text => "Select the topics" ); } sub select_info { my ($self, $first) = @_; my $name = $self->query->param('handout_name') || die "Missing handout name\n"; my $info = Info->new($name); my @topics = (); my $topics = ""; # build new information if ( $first ) { my $item; foreach my $topic ( $info->topics ) { if ( $first->field($topic) ) { $item = $topic; $item =~ s/topic_//; push @topics, $item; } } $topics = join(" ", @topics); } else { $topics = $self->query->param('topic_list'); @topics = split( /\s+/, $topics ); } my @fields = $info->info( @topics );; my $form = CGI::FormBuilder->new( method => $method, name => 'select_info', fields => \@fields, submit => [ 'Show Handout', 'Main Menu' ], reset => 0, text => 'Select Handout Info', options => $info->info_options( @topics ), ); $info->info_fields($form, @topics); $form->field(name => 'rm', value => "select_info", force => 1, type => 'hidden'); $form->field(name => 'handout_name', value => $name, force => 1,type => 'hidden'); $form->field(name => 'topic_list', value => $topics, force => 1,type => 'hidden'); if ( $form->submitted eq 'Show Handout' ) { return $self->show_handout($info, $form, \@topics); } elsif ( $form->submitted eq 'Main Menu' ) { return $self->splash(); } return $form->render( text => "Select the Info" ); } sub show_handout { my ($self, $info, $picks, $topics) = @_; return $self->splash() unless $info; my $name = $self->query->param('handout_name') || die "Missing handout name\n"; $info = Info->new($name) unless $info; my @topics = (); @topics = @$topics if $topics; $topics = ""; # build new information if ( $picks ) { $topics = join(" ", @topics); } else { $picks = {}; $topics = $self->query->param('topic_list'); @topics = split( /\s+/, $topics ); } my %labels = (); my @fields = $info->fields( $picks, \%labels, @topics );; my $form = CGI::FormBuilder->new( method => $method, name => 'select_info', fields => \@fields, labels => \%labels, submit => [ 'Main Menu' ], reset => 0, text => 'Handout', values => $info->show_options( $picks, @topics ), ); $info->show_fields($picks, $form, @topics); $form->field(name => 'rm', value => "show_handout", force => 1, type => 'hidden'); $form->field(name => 'handout_name', value => $name, force => 1,type => 'hidden'); $form->field(name => 'topic_list', value => $topics, force => 1,type => 'hidden'); return "
" . $form->render( valign => "top" ) . ""; } sub import_handout { my $self = shift; my $text = shift || "Create a handout name and import topics"; my @fields = qw(handout_name filename ); my $form = CGI::FormBuilder->new( enctype => 'multipart/form-data', name => 'create_handout_topics', method => 'POST', fields => \@fields, validate => { handout_name => '/^[A-Za-z][\dA-Za-z_]{1,30}$/', }, submit => [ 'Submit', 'Main Menu' ], values => { handout_name => 'name_of_topics_file' }, text => 'Import a text handout file', ); $form->field(name => 'handout_name', comment => 'must be alphanumeric, can use underscores, under 30 characters'); $form->field(name => 'filename', type => 'file', comment => "select a file"); $form->field(name => 'rm', value => "import_handout", force => 1,type => 'hidden'); # And then get to your file the same way as CGI.pm: if ($form->submitted eq 'Submit' ) { my $file = $form->field('filename'); my $name = $form->field('handout_name'); if ( $file and $name ) { my $info = Info->import( $name, $file ); return $self->splash("Handout $name has been imported"); } else { return $form->render( text => "Handout name and filename are required to import a file"); } } elsif ( $form->submitted eq 'Main Menu' ) { return $self->splash(); } else { return $form->render( text => $text ); } } 1; # true returned for library load __END__ =head1 NAME Handout - Web Application for TCM handouts =head1 SYNOPSIS $app = new Handout; $app->run(); =head1 DESCRIPTION A web application to respond with TCM Handouts as needed from a list of keywords. o topic o info o table rows o table columns First pass selects topics by check. Second pass selects info by check. A table and its columns or rows may be selected as well. Handouts are show as separate screens so that one may keep selecting and choosing the proper handout. =head1 Run Modes In this framework all screens are accomplished with run modes which encapsulates all of our electronic web commerce product. All files have to be written to a accessible directory for everybody -- data. =over 4 =item splash Main menu screen. =item select_handout Select a handout topics file from a list. =item select_topics Select the topics desired from the handout file. =item select_info Select the information for the handout. =item show_handout Show in a separate screen the selected items for printing. =item import_handout Import a handout file from the PC to the server which holds a copy of the files. CAUTION: Any imported file may delete the handout file that is already there. =back 4 =head1 Object Design Handout.pm is a CGI::Application object which manages all screens. The handout object uses the Info.pm object to manage all data. =head1 TODO x framework x reader x parser x import x topics x info x simple x table x show o image The ability to add images would help for instructions for exercises or other visual related information. =head1 ENVIRONMENT VARIABLES REQUEST_METHOD - form method defaults to POST =head1 BUGS The table caption is repeated twice. Small tables will wrap the caption on the table. =head1 AUTHOR David Scott L =cut
Hosted by www.Geocities.ws

1