#!/usr/bin/perl ####################### # config_mylibrary.pl # ####################### # Robert Fox # DAIAD - October 2004 # first draft - 10-22-2004 # The purpose of this script is to allow command line editing of the MyLibrary 3.x Config.pm file. # The Config.pm file could contain a potentially unlimited number of instance configurations for one # host. The script should be invoked from the command line and it will prompt the user for options. # First, the proper Config.pm file must be located in the MyLibrary code tree. Once found, the options # for the primary configuration and optional instance configurations can be added or manipulated. use Carp qw/croak/; use Term::Interact; use strict; BEGIN { unshift @INC, "./lib"; } ################## # Configuration # Please do not change this value unless you really know what you are doing. my $config_module = 'Config.pm'; =head1 NAME configure_mylibrary.pl =head1 SYNOPSIS # subroutines my $inc_path = get_config(); my $primary = get_primary($inc_path); my $instances_info = get_instances($inc_path); main_menu(); options_menu('opt_group' => $opt_group, 'type' => 'alternate', 'name' => 'my_instance'); instance_menu('opt_group' => $instances_info, 'action' => 'add'); modify_scalar('opt_group' => $primary, 'type' => 'primary', 'option' => 'DATA_SOURCE'); modify_ssi_pages('opt_group' => $primary, 'type' => 'primary', 'action' => 'menu'); clear_screen(); demystify($line, 'DATA_SOURCE'); =head1 DESCRIPTION This script allows systems administrators to modify MyLibrary configuration modules on hosts where MyLibrary is installed. It is a command line interface which is menu driven. Each menu provides a brief set of instructions along with several menu choices. All input occurs from standard input. This will allow the user to add, delete and modify the appropriate options in the MyLibrary configuration module. The script attempts to find the appropriate Config.pm file, according to the include path for Perl. =head1 SUBROUTINES This section describes the various subroutines that make up this application. =head2 get_config() This subroutine will locate and read in options from a specific Config.pm module which has already been installed on a particular system. The Config.pm module should be installed in a typical Perl path where it can be found and manipulated. The user running this script should have both read and write rights to the Perl INC directories (most likely root). =head2 get_primary() This subroutine takes as an argument the INC path wherein the Config.pm module was located. It reads in the primary (or default) configuration options so that they can be manipulated. =head2 get_instances() This subroutine is very similar to the get_primary subroutine, except that it reads in the alternate instance information in order that alternate instance options can be edited, and so that new instances can be created or old instances deleted. =head2 main_menu() This subroutine simply prints the main menu to standard out. =head2 options_menu() This subroutine calls up the options menu for a given instance and presents a list of options which can be manipulated by the user. It takes as arguments the option group reference being modified (primary or alternate), the type of option reference, and if an alternate instance in being modified, the instance name. =head2 instance_menu() This subroutine calls up the brief instance menu so that alternate instances can be selected for manipulation. It takes as arguments the instance reference followed by the action to be taken (add, edit or delete instances). =head2 modify_scalar() This subroutine allows for the manipulation of a particular option in any given instance. It takes as arguments the instance reference, they instance type, and the option name. =head2 modify_ssi_pages() Due to the complex nature of SSI (server side include) pages which can be included in a MyLibrary template, a separate subroutine is required in order to manipulate those options. It takes as arguments the instance reference, the instance type, and the action to be taken. =head2 clear_screen() This subroutine simply clears the screen between terminal menus. Efforts have been taken in order to make sure that this subroutine will work on any operating system. =head2 demystify() This subroutine performs some regular expression manipulations on a string that is fed to it, once the information has been read from the Config module. =head1 HISTORY First draft October 2004. Ready for prime time on 11/2/2004. =head1 AUTHOR Robert Fox =cut ############ # main my $inc_path = get_config(); my $primary = get_primary($inc_path); my $instances_info = get_instances($inc_path); main_menu(); ############### # subroutines sub get_config { # find the appropriate Config.pm file my $inc_value; foreach my $value (@INC) { if (-e "$value/MyLibrary/$config_module" ) { open ('CONFIG', "+<${value}/MyLibrary/$config_module"); $inc_value = $value; } } # Make sure file is a valid Config.pm package my $n = 0; my $config_found = 0; foreach my $line () { $n++; if ($n == 1) { chop($line); unless ($line eq 'package MyLibrary::Config;') { croak ('This does not appear to be a valid MyLibrary Configuration module.'); } } $config_found = 1; } close(CONFIG); unless ($config_found) { croak('No appropriate MyLibrary config module could be found.'); } open ('CONFIG', "+<${inc_value}/MyLibrary/$config_module"); return $inc_value; } sub options_menu { my %opts = @_; my $opt_group = $opts{'opt_group'}; my $type = $opts{'type'}; my $name = $opts{'name'}; clear_screen(); my ($data_source, $username, $password, $ml_key, $session_dir, $relative_path, $cookie_domain, $home_url, $scripts_url, $secure_scripts_url, $name_of_application, $javascript_url, $css_url, $ssi_url, $image_url, $index_dir); if ($type eq 'primary') { $data_source = $opt_group->{'DATA_SOURCE'}; $username = $opt_group->{'USERNAME'}; $password = $opt_group->{'PASSWORD'}; $ml_key = $opt_group->{'ML_KEY'}; $session_dir = $opt_group->{'SESSION_DIR'}; $relative_path = $opt_group->{'RELATIVE_PATH'}; $cookie_domain = $opt_group->{'COOKIE_DOMAIN'}; $home_url = $opt_group->{'HOME_URL'}; $scripts_url = $opt_group->{'SCRIPTS_URL'}; $secure_scripts_url = $opt_group->{'SECURE_SCRIPTS_URL'}; $name_of_application = $opt_group->{'NAME_OF_APPLICATION'}; $javascript_url = $opt_group->{'JAVASCRIPT_URL'}; $css_url = $opt_group->{'CSS_URL'}; $ssi_url = $opt_group->{'SSI_URL'}; $image_url = $opt_group->{'IMAGE_URL'}; $index_dir = $opt_group->{'INDEX_DIR'}; } elsif ($type eq 'alternate') { $data_source = $opt_group->{$name}->{'DATA_SOURCE'}; $username = $opt_group->{$name}->{'USERNAME'}; $password = $opt_group->{$name}->{'PASSWORD'}; $ml_key = $opt_group->{$name}->{'ML_KEY'}; $session_dir = $opt_group->{$name}->{'SESSION_DIR'}; $relative_path = $opt_group->{$name}->{'RELATIVE_PATH'}; $cookie_domain = $opt_group->{$name}->{'COOKIE_DOMAIN'}; $home_url = $opt_group->{$name}->{'HOME_URL'}; $scripts_url = $opt_group->{$name}->{'SCRIPTS_URL'}; $secure_scripts_url = $opt_group->{$name}->{'SECURE_SCRIPTS_URL'}; $name_of_application = $opt_group->{$name}->{'NAME_OF_APPLICATION'}; $javascript_url = $opt_group->{$name}->{'JAVASCRIPT_URL'}; $css_url = $opt_group->{$name}->{'CSS_URL'}; $ssi_url = $opt_group->{$name}->{'SSI_URL'}; $image_url = $opt_group->{$name}->{'IMAGE_URL'}; $index_dir = $opt_group->{$name}->{'INDEX_DIR'}; } my $instance_title; if ($type eq 'primary') { $instance_title = 'Primary'; } elsif ($type eq 'alternate') { $instance_title = 'Alternate'; } # Display initial instrunctions print "\nMyLibrary 3.x $instance_title Configuration\n"; print "\nPlease choose one of the options below to edit that configuration value\n\n"; # Menu if ($type eq 'primary') { print "Primary Instance Configuration Menu\n"; print "===================================\n"; } elsif ($type eq 'alternate') { print "Alternate Instance Configuration Menu\n"; print "=====================================\n"; } print "\n"; if ($type eq 'alternate') { print "Instance code: $name\n"; print "\n"; } print "[1] Data Source (currently: $data_source)\n"; print "[2] Database Username (currently: $username)\n"; print "[3] Database Password (currently: $password)\n"; print "[4] MyLibrary Key Location (currently: $ml_key)\n"; print "[5] Sessions Directory (currently: $session_dir)\n"; print "[6] Web Relative Path (currently: $relative_path)\n"; print "[7] Browser Cookie Domain (currently: $cookie_domain)\n"; print "[8] Home URL (currently: $home_url)\n"; print "[9] CGI Scripts URL (currently: $scripts_url)\n"; print "[10] CGI Secure Scripts URL (currently: $secure_scripts_url)\n"; print "[11] Name of Application (currently: $name_of_application)\n"; print "[12] Javascript URL (currently: $javascript_url)\n"; print "[13] Cascading Style Sheet URL (currently: $css_url)\n"; print "[14] Server Side Inlcudes URL (currently: $ssi_url)\n"; print "[15] Images URL (currently: $image_url)\n"; print "[16] SSI Page names (choose this option to see values)\n"; print "[17] Local Indexes Directory (currently: $index_dir)\n"; print "\n"; print "[R]eturn to main menu\n"; if ($type eq 'alternate') { print "[G]o to previous menu\n"; } print "[Q]uit and save changes\n"; print "\n"; my $prompt = Term::Interact->new(); my $choice = $prompt->get( msg => '', prompt => 'Please indicate your choice: ', re_prompt => 'Invalid selection. Please select one of the options listed above: ', check => ['1', '2', '3', '4', '5', '6', '7', '8', '9', '10', '11', '12', '13', '14', '15', '16', '17', 'R', 'G', 'Q'], ); # Resolve choice if ($choice eq 'R') { main_menu(); } elsif ($choice eq 'G') { if ($type eq 'alternate') { instance_menu('opt_group' => $instances_info, 'action' => 'edit'); } else { main_menu(); } } elsif ($choice eq 'Q') { write_file(); } elsif ($choice eq '1') { if ($type eq 'primary') { modify_scalar('opt_group' => $opt_group, 'type' => 'primary', 'option' => 'DATA_SOURCE'); } elsif ($type eq 'alternate') { modify_scalar('opt_group' => $opt_group, 'type' => 'alternate', 'option' => 'DATA_SOURCE', 'instance_name' => $name); } } elsif ($choice eq '2') { if ($type eq 'primary') { modify_scalar('opt_group' => $opt_group, 'type' => 'primary', 'option' => 'USERNAME'); } elsif ($type eq 'alternate') { modify_scalar('opt_group' => $opt_group, 'type' => 'alternate', 'option' => 'USERNAME', 'instance_name' => $name); } } elsif ($choice eq '3') { if ($type eq 'primary') { modify_scalar('opt_group' => $opt_group, 'type' => 'primary', 'option' => 'PASSWORD'); } elsif ($type eq 'alternate') { modify_scalar('opt_group' => $opt_group, 'type' => 'alternate', 'option' => 'PASSWORD', 'instance_name' => $name); } } elsif ($choice eq '4') { if ($type eq 'primary') { modify_scalar('opt_group' => $opt_group, 'type' => 'primary', 'option' => 'ML_KEY'); } elsif ($type eq 'alternate') { modify_scalar('opt_group' => $opt_group, 'type' => 'alternate', 'option' => 'ML_KEY', 'instance_name' => $name); } } elsif ($choice eq '5') { if ($type eq 'primary') { modify_scalar('opt_group' => $opt_group, 'type' => 'primary', 'option' => 'SESSION_DIR'); } elsif ($type eq 'alternate') { modify_scalar('opt_group' => $opt_group, 'type' => 'alternate', 'option' => 'SESSION_DIR', 'instance_name' => $name); } } elsif ($choice eq '6') { if ($type eq 'primary') { modify_scalar('opt_group' => $opt_group, 'type' => 'primary', 'option' => 'RELATIVE_PATH'); } elsif ($type eq 'alternate') { modify_scalar('opt_group' => $opt_group, 'type' => 'alternate', 'option' => 'RELATIVE_PATH', 'instance_name' => $name); } } elsif ($choice eq '7') { if ($type eq 'primary') { modify_scalar('opt_group' => $opt_group, 'type' => 'primary', 'option' => 'COOKIE_DOMAIN'); } elsif ($type eq 'alternate') { modify_scalar('opt_group' => $opt_group, 'type' => 'alternate', 'option' => 'COOKIE_DOMAIN', 'instance_name' => $name); } } elsif ($choice eq '8') { if ($type eq 'primary') { modify_scalar('opt_group' => $opt_group, 'type' => 'primary', 'option' => 'HOME_URL'); } elsif ($type eq 'alternate') { modify_scalar('opt_group' => $opt_group, 'type' => 'alternate', 'option' => 'HOME_URL', 'instance_name' => $name); } } elsif ($choice eq '9') { if ($type eq 'primary') { modify_scalar('opt_group' => $opt_group, 'type' => 'primary', 'option' => 'SCRIPTS_URL'); } elsif ($type eq 'alternate') { modify_scalar('opt_group' => $opt_group, 'type' => 'alternate', 'option' => 'SCRIPTS_URL', 'instance_name' => $name); } } elsif ($choice eq '10') { if ($type eq 'primary') { modify_scalar('opt_group' => $opt_group, 'type' => 'primary', 'option' => 'SECURE_SCRIPTS_URL'); } elsif ($type eq 'alternate') { modify_scalar('opt_group' => $opt_group, 'type' => 'alternate', 'option' => 'SECURE_SCRIPTS_URL', 'instance_name' => $name); } } elsif ($choice eq '11') { if ($type eq 'primary') { modify_scalar('opt_group' => $opt_group, 'type' => 'primary', 'option' => 'NAME_OF_APPLICATION'); } elsif ($type eq 'alternate') { modify_scalar('opt_group' => $opt_group, 'type' => 'alternate', 'option' => 'NAME_OF_APPLICATION', 'instance_name' => $name); } } elsif ($choice eq '12') { if ($type eq 'primary') { modify_scalar('opt_group' => $opt_group, 'type' => 'primary', 'option' => 'JAVASCRIPT_URL'); } elsif ($type eq 'alternate') { modify_scalar('opt_group' => $opt_group, 'type' => 'alternate', 'option' => 'JAVASCRIPT_URL', 'instance_name' => $name); } } elsif ($choice eq '13') { if ($type eq 'primary') { modify_scalar('opt_group' => $opt_group, 'type' => 'primary', 'option' => 'CSS_URL'); } elsif ($type eq 'alternate') { modify_scalar('opt_group' => $opt_group, 'type' => 'alternate', 'option' => 'CSS_URL', 'instance_name' => $name); } } elsif ($choice eq '14') { if ($type eq 'primary') { modify_scalar('opt_group' => $opt_group, 'type' => 'primary', 'option' => 'SSI_URL'); } elsif ($type eq 'alternate') { modify_scalar('opt_group' => $opt_group, 'type' => 'alternate', 'option' => 'SSI_URL', 'instance_name' => $name); } } elsif ($choice eq '15') { if ($type eq 'primary') { modify_scalar('opt_group' => $opt_group, 'type' => 'primary', 'option' => 'IMAGE_URL'); } elsif ($type eq 'alternate') { modify_scalar('opt_group' => $opt_group, 'type' => 'alternate', 'option' => 'IMAGE_URL', 'instance_name' => $name); } } elsif ($choice eq '16') { if ($type eq 'primary') { modify_ssi_pages('opt_group' => $opt_group, 'type' => 'primary', 'action' => 'menu'); } elsif ($type eq 'alternate') { modify_ssi_pages('opt_group' => $opt_group, 'type' => 'alternate', 'action' => 'menu', 'instance_name' => $name); } } elsif ($choice eq '17') { if ($type eq 'primary') { modify_scalar('opt_group' => $opt_group, 'type' => 'primary', 'option' => 'INDEX_DIR'); } elsif ($type eq 'alternate') { modify_scalar('opt_group' => $opt_group, 'type' => 'alternate', 'option' => 'INDEX_DIR', 'instance_name' => $name); } } } sub modify_ssi_pages { my %opts = @_; my $opt_group = $opts{'opt_group'}; my $type = $opts{'type'}; my $name = $opts{'instance_name'}; my $action = $opts{'action'}; my $delete_code = $opts{'delete_code'}; my $instance_name; if ($type eq 'primary') { $instance_name = 'Primary'; } elsif ($type eq 'alternate') { $instance_name = "$name"; } if ($action eq 'menu') { clear_screen(); # Display initial instrunctions my $title = "\n$instance_name Instance SSI Pages Configuration"; my $underline; for (my $i = 1; $i <= length($title); $i++) { $underline .= '='; } print "$title\n"; print "$underline\n"; print "\n"; print "The following is the list of SSI pages available for incorporation into page templates. Please select a number in order to delete a particular SSI page or choose [A] to add another SSI page to the list. The pages are listed with their codes to the left of the arrow and their page names to the right.\n"; print "\n"; my %page_numbers = (); my @valid_options = (); if ($type eq 'primary') { my %ssi_pages = %{$opt_group->{'SSI_PAGES'}}; my $n = 0; foreach my $page_code (keys %ssi_pages) { $n++; print "[$n] $page_code -> $ssi_pages{$page_code}\n"; $page_numbers{$n} = $page_code; push(@valid_options, $n); } } elsif ($type eq 'alternate') { if (scalar(%{$opt_group->{$name}->{'SSI_PAGES'}})) { my %ssi_pages = %{$opt_group->{$name}->{'SSI_PAGES'}}; my $n = 0; foreach my $page_code (keys %ssi_pages) { $n++; print "[$n] $page_code -> $ssi_pages{$page_code}\n"; $page_numbers{$n} = $page_code; push(@valid_options, $n); } } else { print "No previous SSI page associations found.\n"; } } push(@valid_options, 'A'); push(@valid_options, 'R'); push(@valid_options, 'G'); push(@valid_options, 'Q'); print "\n"; print "[A]dd new SSI option\n"; print "\n"; print "[R]eturn to main menu\n"; print "[G]o to preivous menu\n"; print "[Q]uit and save changes\n"; print "\n"; my $prompt = Term::Interact->new(); my $choice = $prompt->get( msg => '', prompt => 'Please indicate your choice: ', re_prompt => 'Invalid selection. Please select from one of the options above: ', check => [ @valid_options ], ); # Resolve choice if ($choice eq 'R') { main_menu(); } elsif ($choice eq 'Q') { write_file(); } elsif ($choice eq 'G') { if ($type eq 'primary') { options_menu('opt_group' => $opt_group, 'type' => 'primary'); } elsif ($type eq 'alternate') { options_menu('opt_group' => $opt_group, 'type' => 'alternate', 'name' => $name); } } elsif ($choice =~ /(\d+)/) { my $delete_code = $page_numbers{$1}; if ($type eq 'primary') { modify_ssi_pages('opt_group' => $opt_group, 'type' => $type, 'action' => 'delete', 'delete_code' => "$delete_code"); } elsif ($type eq 'alternate') { modify_ssi_pages('opt_group' => $opt_group, 'type' => $type, 'action' => 'delete', 'instance_name' => $name, 'delete_code' => "$delete_code"); } } elsif ($choice eq 'A') { if ($type eq 'primary') { modify_ssi_pages('opt_group' => $opt_group, 'type' => $type, 'action' => 'add'); } elsif ($type eq 'alternate') { modify_ssi_pages('opt_group' => $opt_group, 'type' => $type, 'action' => 'add', 'instance_name' => $name); } } } elsif ($action eq 'delete') { my $prompt = Term::Interact->new(); my $choice = $prompt->get( msg => "You indicated that you would like to delete the SSI page $delete_code from this configuration.\n", prompt => 'Please confirm your choice [Y|n]: ', re_prompt => 'Please indicate either Y or n: ', check => ['Y', 'n'], ); if ($choice eq 'Y') { if ($type eq 'primary') { delete $opt_group->{'SSI_PAGES'}->{$delete_code}; } elsif ($type eq 'alternate') { delete $opt_group->{$name}->{'SSI_PAGES'}->{$delete_code}; } } if ($type eq 'primary') { modify_ssi_pages('opt_group' => $opt_group, 'type' => $type, 'action' => 'menu'); } elsif ($type eq 'alternate') { modify_ssi_pages('opt_group' => $opt_group, 'type' => $type, 'action' => 'menu', 'instance_name' => $name); } } elsif ($action eq 'add') { print "\nYou have chosen to add a new SSI page to this configuration. At the prompt below, please indicate first the code you would like to use for this SSI segment followed by a comma followed by a space and the name of the SSI page you would like to add.\n"; my $prompt = Term::Interact->new(); my $choice = $prompt->get( msg => '', default => ['code_name', 'page_name'], prompt => 'Please indicate the new SSI page code followed by the page name [code_name, page_name]: ', re_prompt => 'Please re-enter your code and page name. Make sure you use a comma to separate values: ', confirm => '1', delimiter => ',', max_elem => 2, check => [ qr/.+/ ], ); my @choices = @{$choice}; if (scalar(@choices) != 2) { print "\n"; print "It appears that perhaps you did not enter both of the required parameters. Are you sure that you entered both the SSI code name as well as a page name that is accessible via the SSI URL? [Y|n]"; my $answer = ; chop($answer); # start over if necessary if ($answer eq 'n') { modify_ssi_pages('opt_group' => $opt_group, 'type' => $type, 'action' => 'menu'); } } if ($type eq 'primary') { my %ssi_pages = %{$opt_group->{'SSI_PAGES'}}; $ssi_pages{$choices[0]} = $choices[1]; $opt_group->{'SSI_PAGES'} = \%ssi_pages; } elsif ($type eq 'alternate') { my %ssi_pages = (); if (scalar(%{$opt_group->{$name}->{'SSI_PAGES'}})) { %ssi_pages = %{$opt_group->{$name}->{'SSI_PAGES'}}; } $ssi_pages{$choices[0]} = $choices[1]; $opt_group->{$name}->{'SSI_PAGES'} = \%ssi_pages; } if ($type eq 'primary') { modify_ssi_pages('opt_group' => $opt_group, 'type' => $type, 'action' => 'menu'); } elsif ($type eq 'alternate') { modify_ssi_pages('opt_group' => $opt_group, 'type' => $type, 'action' => 'menu', 'instance_name' => $name); } } } sub modify_scalar { my %opts = @_; my $opt_group = $opts{'opt_group'}; my $type = $opts{'type'}; my $name = $opts{'instance_name'}; my $option = $opts{'option'}; my ($option_val, $instance_name, $option_title); if ($type eq 'primary') { $option_val = $opt_group->{$option}; $instance_name = 'Primary'; } elsif ($type eq 'alternate') { $option_val = $opt_group->{$name}->{$option}; $instance_name = "$name"; } my %option_name = ('DATA_SOURCE' => 'Datasource', 'USERNAME' => 'Username', 'PASSWORD' => 'Password', 'ML_KEY' => 'MyLibrary Key Location', 'SESSION_DIR' => 'Sessions Directory', 'RELATIVE_PATH' => 'Web Relative Path', 'COOKIE_DOMAIN' => 'Browser Cookie Domain', 'HOME_URL' => 'Home URL', 'SCRIPTS_URL' => 'CGI Scripts URL', 'SECURE_SCRIPTS_URL' => 'CGI Secure Scripts URL', 'NAME_OF_APPLICATION' => 'Name of Application', 'JAVASCRIPT_URL' => 'Javascript URL', 'CSS_URL' => 'Cascading Style Sheet URL', 'SSI_URL' => 'Server Side Inlcudes URL', 'IMAGE_URL' => 'Images URL', 'INDEX_DIR' => 'Local Indexes Directory'); foreach my $op_name (keys %option_name) { if ($op_name eq $option) { $option_title = $option_name{$op_name}; last; } } clear_screen(); # Display initial instrunctions my $title = "Modify $instance_name $option_title"; my $underline; for (my $i = 1; $i <= length($title); $i++) { $underline .= '='; } print "$title\n"; print "$underline\n"; print "\n"; print "Instructions: The current value for this option is indicated below. Please type in the new value you would like to set for this option.\n"; print "\n"; print "Current $instance_name instance value: \'$option_val\'\n"; print "\n"; my $prompt = Term::Interact->new(); my $choice = $prompt->get( msg => '', prompt => 'Please indicate new value: ', confirm => '1', ); if ($type eq 'primary') { $opt_group->{$option} = "$choice"; options_menu('opt_group' => $opt_group, 'type' => 'primary'); } elsif ($type eq 'alternate') { $opt_group->{$name}->{$option} = "$choice"; options_menu('opt_group' => $opt_group, 'type' => 'alternate', 'name' => $name); } } sub main_menu { clear_screen(); # Display initial instrunctions print "\nMyLibrary 3.x Configuration Utility\n"; print "Please choose one of the options below. Terminating the program will apply any changes made.\n\n"; # Menu print "Main Menu\n"; print "=========\n"; print "\n"; print "[E]dit Primary Configuration\n"; print "[A]dd, [e]dit or [d]elete Alternative Instance Configuration\n"; print "[Q]uit Program\n"; print "\n"; print "Using config file: $inc_path/MyLibrary/$config_module\n"; print "\n"; my $prompt = Term::Interact->new(); my $choice = $prompt->get( msg => '', prompt => 'Please indicate your choice: ', re_prompt => 'Invalid selection. Please select one of the options listed above: ', check => [ 'E', 'A', 'Q', 'e', 'd' ], ); # Resolve choice if ($choice eq 'E') { options_menu('opt_group' => $primary, 'type' => 'primary'); } elsif ($choice eq 'A') { instance_menu('opt_group' => $instances_info, 'action' => 'add'); } elsif ($choice eq 'e') { instance_menu('opt_group' => $instances_info, 'action' => 'edit'); } elsif ($choice eq 'd') { instance_menu('opt_group' => $instances_info, 'action' => 'delete'); } elsif ($choice eq 'Q') { write_file(); } } sub write_file { open(NEWFILE, ">$inc_path/MyLibrary/Config_new.pm"); print NEWFILE "package MyLibrary::Config\;\n"; print NEWFILE "\n"; print NEWFILE "\tour \$DATA_SOURCE = \'$primary->{'DATA_SOURCE'}\'\;\n"; print NEWFILE "\tour \$USERNAME = \'$primary->{'USERNAME'}\'\;\n"; print NEWFILE "\tour \$PASSWORD = \'$primary->{'PASSWORD'}\'\;\n"; print NEWFILE "\tour \$ML_KEY = \'$primary->{'ML_KEY'}\'\;\n"; print NEWFILE "\tour \$SESSION_DIR = \'$primary->{'SESSION_DIR'}\'\;\n"; print NEWFILE "\tour \$RELATIVE_PATH = \'$primary->{'RELATIVE_PATH'}\'\;\n"; print NEWFILE "\tour \$COOKIE_DOMAIN = \'$primary->{'COOKIE_DOMAIN'}\'\;\n"; print NEWFILE "\tour \$HOME_URL = \'$primary->{'HOME_URL'}\'\;\n"; print NEWFILE "\tour \$SCRIPTS_URL = \'$primary->{'SCRIPTS_URL'}\'\;\n"; print NEWFILE "\tour \$SECURE_SCRIPTS_URL = \'$primary->{'SECURE_SCRIPTS_URL'}\'\;\n"; print NEWFILE "\tour \$NAME_OF_APPLICATION = \'$primary->{'NAME_OF_APPLICATION'}\'\;\n"; print NEWFILE "\tour \$JAVASCRIPT_URL = \'$primary->{'JAVASCRIPT_URL'}\'\;\n"; print NEWFILE "\tour \$CSS_URL = \'$primary->{'CSS_URL'}\'\;\n"; print NEWFILE "\tour \$SSI_URL = \'$primary->{'SSI_URL'}\'\;\n"; print NEWFILE "\tour \$IMAGE_URL = \'$primary->{'IMAGE_URL'}\'\;\n"; my $page_values; foreach my $page_ref (keys %{$primary->{'SSI_PAGES'}}) { $page_values .= "\'$page_ref\', \'$primary->{'SSI_PAGES'}->{$page_ref}\', "; } chop($page_values); chop($page_values); print NEWFILE "\tour \%SSI_PAGES = ($page_values)\;\n"; print NEWFILE "\tour \$INDEX_DIR = \'$primary->{'INDEX_DIR'}\'\;\n"; print NEWFILE "\n"; my $instances_string; foreach my $instance_name (keys %{$instances_info}) { my $particular_instance .= "\'$instance_name\' => {"; $particular_instance .= "\'DATA_SOURCE\' => \'$instances_info->{$instance_name}->{'DATA_SOURCE'}\', "; $particular_instance .= "\'USERNAME\' => \'$instances_info->{$instance_name}->{'USERNAME'}\', "; $particular_instance .= "\'PASSWORD\' => \'$instances_info->{$instance_name}->{'PASSWORD'}\', "; $particular_instance .= "\'ML_KEY\' => \'$instances_info->{$instance_name}->{'ML_KEY'}\', "; $particular_instance .= "\'SESSION_DIR\' => \'$instances_info->{$instance_name}->{'SESSION_DIR'}\', "; $particular_instance .= "\'RELATIVE_PATH\' => \'$instances_info->{$instance_name}->{'RELATIVE_PATH'}\', "; $particular_instance .= "\'COOKIE_DOMAIN\' => \'$instances_info->{$instance_name}->{'COOKIE_DOMAIN'}\', "; $particular_instance .= "\'HOME_URL\' => \'$instances_info->{$instance_name}->{'HOME_URL'}\', "; $particular_instance .= "\'SCRIPTS_URL\' => \'$instances_info->{$instance_name}->{'SCRIPTS_URL'}\', "; $particular_instance .= "\'SECURE_SCRIPTS_URL\' => \'$instances_info->{$instance_name}->{'SECURE_SCRIPTS_URL'}\', "; $particular_instance .= "\'NAME_OF_APPLICATION\' => \'$instances_info->{$instance_name}->{'NAME_OF_APPLICATION'}\', "; $particular_instance .= "\'JAVASCRIPT_URL\' => \'$instances_info->{$instance_name}->{'JAVASCRIPT_URL'}\', "; $particular_instance .= "\'CSS_URL\' => \'$instances_info->{$instance_name}->{'CSS_URL'}\', "; $particular_instance .= "\'SSI_URL\' => \'$instances_info->{$instance_name}->{'SSI_URL'}\', "; $particular_instance .= "\'IMAGE_URL\' => \'$instances_info->{$instance_name}->{'IMAGE_URL'}\', "; my %ssi_pages = %{$instances_info->{$instance_name}->{'SSI_PAGES'}}; my $ssi_string; foreach my $page (keys %ssi_pages) { $ssi_string .= "\'$page\', "; $ssi_string .= "\'$ssi_pages{$page}\', "; } chop($ssi_string); chop($ssi_string); $particular_instance .= "\'SSI_PAGES\' => [$ssi_string], "; $particular_instance .= "\'INDEX_DIR\' => \'$instances_info->{$instance_name}->{'INDEX_DIR'}\'}, "; $instances_string .= $particular_instance; } chop($instances_string); chop($instances_string); print NEWFILE "\tmy \%instances = ($instances_string)\;\n"; print NEWFILE "\n"; print NEWFILE "\n"; # put remaining code into config module print NEWFILE "sub instance {\n"; print NEWFILE "\n"; print NEWFILE "\tmy \$class = shift\;\n"; print NEWFILE "\tmy \$instance = shift\;\n"; print NEWFILE "\n"; print NEWFILE "\tif (\$instance && \$instance ne \'default\') \{\n"; print NEWFILE "\t\tmy \%instance_params = \%{\$instances\{\$instance}}\;\n"; print NEWFILE "\t\tour \$DATA_SOURCE = \$instance_params\{\'DATA_SOURCE\'}\;\n"; print NEWFILE "\t\tour \$USERNAME = \$instance_params\{\'USERNAME\'}\;\n"; print NEWFILE "\t\tour \$PASSWORD = \$instance_params\{\'PASSWORD\'}\;\n"; print NEWFILE "\t\tour \$ML_KEY = \$instance_params\{\'ML_KEY\'}\;\n"; print NEWFILE "\t\tour \$SESSION_DIR = \$instance_params\{\'SESSION_DIR\'}\;\n"; print NEWFILE "\t\tour \$RELATIVE_PATH = \$instance_params\{\'RELATIVE_PATH\'}\;\n"; print NEWFILE "\t\tour \$COOKIE_DOMAIN = \$instance_params\{\'COOKIE_DOMAIN\'}\;\n"; print NEWFILE "\t\tour \$HOME_URL = \$instance_params{\'HOME_URL\'}\;\n"; print NEWFILE "\t\tour \$SCRIPTS_URL = \$instance_params{\'SCRIPTS_URL\'}\;\n"; print NEWFILE "\t\tour \$SECURE_SCRIPTS_URL = \$instance_params{\'SECURE_SCRIPTS_URL\'}\;\n"; print NEWFILE "\t\tour \$NAME_OF_APPLICATION = \$instance_params{\'NAME_OF_APPLICATION\'}\;\n"; print NEWFILE "\t\tour \$JAVASCRIPT_URL = \$instance_params{\'JAVASCRIPT_URL\'}\;\n"; print NEWFILE "\t\tour \$CSS_URL = \$instance_params{\'CSS_URL\'}\;\n"; print NEWFILE "\t\tour \$SSI_URL = \$instance_params{\'SSI_URL\'}\;\n"; print NEWFILE "\t\tour \$IMAGE_URL = \$instance_params{\'IMAGE_URL\'}\;\n"; print NEWFILE "\t\tour \%SSI_PAGES = \@{\$instance_params\{\'SSI_PAGES\'}}\;\n"; print NEWFILE "\t\tour \$INDEX_DIR = \$instance_params\{\'INDEX_DIR\'}\;\n"; print NEWFILE "\t}\n"; print NEWFILE "\n"; print NEWFILE "}\n"; print NEWFILE "\n"; print NEWFILE "1\;\n"; close NEWFILE; # Finally, put new file in place rename ("$inc_path/MyLibrary/Config_new.pm", "$inc_path/MyLibrary/$config_module"); exit; } sub clear_screen { my $cmd; # Unix style clear screen if ($ENV{'PATH'} =~ /\/\w+\//) { $cmd = 'clear'; # MS Windows style clear screen } elsif ($ENV{'PATH'} =~ /^\d:\\/) { $cmd = 'cls'; } system("$cmd"); } sub instance_menu { my %opts = @_; my $opt_group = $opts{'opt_group'}; my $action = $opts{'action'}; if ($action eq 'add') { my $instance_string; foreach my $instance_name (keys %{$opt_group}) { $instance_name = "\'$instance_name\'"; $instance_string .= "$instance_name "; } chop($instance_string); $instance_string = join(', ', split(/ /, $instance_string)); # Display add menu clear_screen(); print "Instance Creation\n"; print "=================\n"; print "\n"; print "On the following screens you will be prompted for information about the new instance that you would like to create. Instance names that have already been taken will be listed below. Each instance name should be unique or the configuration module will not be able to discern which instance you mean when you invoke the instance method.\n"; print "\n"; print "Current instance code names: $instance_string\n"; print "\n"; my $prompt = Term::Interact->new(); my $choice = $prompt->get( msg => '', prompt => 'Begin by indicating the new instance code name [or enter \'R\' to return to the previous menu]: ', ); print "\n"; if ($choice eq 'R') { main_menu(); } # fill in empty sets for options $opt_group->{$choice}->{'DATA_SOURCE'} = ''; $opt_group->{$choice}->{'USERNAME'} = ''; $opt_group->{$choice}->{'PASSWORD'} = ''; $opt_group->{$choice}->{'ML_KEY'} = ''; $opt_group->{$choice}->{'SESSION_DIR'} = ''; $opt_group->{$choice}->{'RELATIVE_PATH'} = ''; $opt_group->{$choice}->{'COOKIE_DOMAIN'} = ''; $opt_group->{$choice}->{'HOME_URL'} = ''; $opt_group->{$choice}->{'SCRIPTS_URL'} = ''; $opt_group->{$choice}->{'SECURE_SCRIPTS_URL'} = ''; $opt_group->{$choice}->{'NAME_OF_APPLICATION'} = ''; $opt_group->{$choice}->{'JAVASCRIPT_URL'} = ''; $opt_group->{$choice}->{'CSS_URL'} = ''; $opt_group->{$choice}->{'SSI_URL'} = ''; $opt_group->{$choice}->{'IMAGE_URL'} = ''; $opt_group->{$choice}->{'SSI_PAGES'} = {}; $opt_group->{$choice}->{'INDEX_DIR'} = ''; options_menu('opt_group' => $opt_group, 'type' => 'alternate', 'name' => $choice); } elsif ($action eq 'edit') { my $n = 0; my @valid_options = (); my %instance_numbers = (); # Display edit menu clear_screen(); print "Choose Instance to Edit\n"; print "=======================\n"; if (scalar(%{$opt_group})) { foreach my $instance_name (keys %{$opt_group}) { $n++; print "[$n] $instance_name\n"; $instance_numbers{$n} = "$instance_name"; push(@valid_options, $n); } } else { print "\n"; print "There are currently no alternate instances to edit. Please return to the main menu and choose option A.\n"; } print "\n"; print "[R]eturn to main menu\n"; print "[Q]uit and save changes\n"; print "\n"; push(@valid_options, 'R'); push(@valid_options, 'Q'); my $prompt = Term::Interact->new(); my $choice = $prompt->get( msg => '', prompt => 'Please indicate your choice: ', re_prompt => 'Invalid selection. Please select one of the options listed above: ', check => [ @valid_options ], ); # Resolve choice if ($choice eq 'R') { main_menu(); } elsif ($choice =~ /(\d+)/) { my $edit_code = $instance_numbers{$1}; options_menu('opt_group' => $opt_group, 'type' => 'alternate', 'name' => $edit_code); } elsif ($choice eq 'Q') { write_file(); } } elsif ($action eq 'delete') { my $n = 0; my @valid_options = (); my %instance_numbers = (); # Display edit menu clear_screen(); print "Choose Instance to Delete\n"; print "=========================\n"; print "\n"; print "Please select from the options below which instance you would like to delete.\n"; if (scalar(%{$opt_group})) { foreach my $instance_name (keys %{$opt_group}) { $n++; print "[$n] $instance_name\n"; $instance_numbers{$n} = "$instance_name"; push(@valid_options, $n); } } else { print "\n"; print "There are currently no alternate instances to delete.\n"; } print "\n"; print "[R]eturn to main menu\n"; print "[Q]uit and save changes\n"; print "\n"; push(@valid_options, 'R'); push(@valid_options, 'Q'); my $prompt = Term::Interact->new(); my $choice = $prompt->get( msg => '', prompt => 'Please indicate your choice: ', re_prompt => 'Invalid selection. Please select one of the options listed above: ', confirm => '0', check => [ @valid_options ], ); # Resolve choice if ($choice eq 'R') { main_menu(); } elsif ($choice =~ /(\d+)/) { my $number = $1; print "\n"; print "You entered \'$number\'. Is this correct? [Y|n]: "; my $confirmation = ; chop($confirmation); if ($confirmation eq 'Y') { my $delete_code = $instance_numbers{$number}; delete($instances_info->{$delete_code}); instance_menu('opt_group' => $instances_info, 'action' => 'delete'); } else { instance_menu('opt_group' => $instances_info, 'action' => 'delete'); } } elsif ($choice eq 'Q') { write_file(); } } } sub get_instances { my $inc_value = shift; my $instances_line; foreach my $line () { # Instances line chop($line); if ($line =~ /my %instances = \(/) { $line =~ s/^\s*//; $line =~ /(my %instances = )(\(.*\);)/; $instances_line = $2; } } # take off the trailing semicolon chop($instances_line); # get all of the instance names $_ = "$instances_line"; my @patterns = /('\w+' => \{)/g; my @instance_names = (); foreach my $pattern (@patterns) { $pattern =~ s/=>//; $pattern =~ s/'//g; $pattern =~ s/ //g; $pattern =~ s/\{//; push(@instance_names, $pattern); } my %instances_info = (); foreach my $name (@instance_names) { my %instance_params = (); $instances_line =~ /'$name' => \{'DATA_SOURCE' => '(.*?)',/; $instance_params{'DATA_SOURCE'} = $1; $instances_line =~ /'$name' => .+?'USERNAME' => '(.*?)',/; $instance_params{'USERNAME'} = $1; $instances_line =~ /'$name' => .+?'PASSWORD' => '(.*?)',/; $instance_params{'PASSWORD'} = $1; $instances_line =~ /'$name' => .+?'ML_KEY' => '(.*?)',/; $instance_params{'ML_KEY'} = $1; $instances_line =~ /'$name' => .+?'SESSION_DIR' => '(.*?)',/; $instance_params{'SESSION_DIR'} = $1; $instances_line =~ /'$name' => .+?'RELATIVE_PATH' => '(.*?)',/; $instance_params{'RELATIVE_PATH'} = $1; $instances_line =~ /'$name' => .+?'COOKIE_DOMAIN' => '(.*?)',/; $instance_params{'COOKIE_DOMAIN'} = $1; $instances_line =~ /'$name' => .+?'HOME_URL' => '(.*?)',/; $instance_params{'HOME_URL'} = $1; $instances_line =~ /'$name' => .+?'SCRIPTS_URL' => '(.*?)',/; $instance_params{'SCRIPTS_URL'} = $1; $instances_line =~ /'$name' => .+?'SECURE_SCRIPTS_URL' => '(.*?)',/; $instance_params{'SECURE_SCRIPTS_URL'} = $1; $instances_line =~ /'$name' => .+?'NAME_OF_APPLICATION' => '(.*?)',/; $instance_params{'NAME_OF_APPLICATION'} = $1; $instances_line =~ /'$name' => .+?'JAVASCRIPT_URL' => '(.*?)',/; $instance_params{'JAVASCRIPT_URL'} = $1; $instances_line =~ /'$name' => .+?'CSS_URL' => '(.*?)',/; $instance_params{'CSS_URL'} = $1; $instances_line =~ /'$name' => .+?'SSI_URL' => '(.*?)',/; $instance_params{'SSI_URL'} = $1; $instances_line =~ /'$name' => .+?'IMAGE_URL' => '(.*?)',/; $instance_params{'IMAGE_URL'} = $1; $instances_line =~ /'$name' => .+?'SSI_PAGES' => \[(.*?)],/; my $ssi_string = $1; $ssi_string =~ s/'//g; my %ssi_options = split(/, /, $ssi_string); $instance_params{'SSI_PAGES'} = \%ssi_options; $instances_line =~ /'$name' => .+?'INDEX_DIR' => '(.*?)'}/; $instance_params{'INDEX_DIR'} = $1; $instances_info{$name} = \%instance_params; } close(CONFIG); open ('CONFIG', "+<${inc_value}/MyLibrary/$config_module"); return \%instances_info; } sub get_primary { my $inc_value = shift; my %primary = (); foreach my $line () { # Data source line chop($line); if ($line =~ /our \$DATA_SOURCE = '/) { $primary{'DATA_SOURCE'} = demystify($line, 'DATA_SOURCE'); next; } # Username line if ($line =~ /our \$USERNAME = '/) { $primary{'USERNAME'} = demystify($line, 'USERNAME'); next; } # Password line if ($line =~ /our \$PASSWORD = '/) { $primary{'PASSWORD'} = demystify($line, 'PASSWORD'); next; } # MyLibrary key line if ($line =~ /our \$ML_KEY = '/) { $primary{'ML_KEY'} = demystify($line, 'ML_KEY'); next; } # Session directory line if ($line =~ /our \$SESSION_DIR = '/) { $primary{'SESSION_DIR'} = demystify($line, 'SESSION_DIR'); next; } # Relative script path if ($line =~ /our \$RELATIVE_PATH = '/) { $primary{'RELATIVE_PATH'} = demystify($line, 'RELATIVE_PATH'); next; } # Cookie domain if ($line =~ /our \$COOKIE_DOMAIN = '/) { $primary{'COOKIE_DOMAIN'} = demystify($line, 'COOKIE_DOMAIN'); next; } # Home URL if ($line =~ /our \$HOME_URL = '/) { $primary{'HOME_URL'} = demystify($line, 'HOME_URL'); next; } # Scripts URL if ($line =~ /our \$SCRIPTS_URL = '/) { $primary{'SCRIPTS_URL'} = demystify($line, 'SCRIPTS_URL'); next; } # Secure scripts URL if ($line =~ /our \$SECURE_SCRIPTS_URL = '/) { $primary{'SECURE_SCRIPTS_URL'} = demystify($line, 'SECURE_SCRIPTS_URL'); next; } # Name of application if ($line =~ /our \$NAME_OF_APPLICATION = '/) { $primary{'NAME_OF_APPLICATION'} = demystify($line, 'NAME_OF_APPLICATION'); next; } # Javascript URL if ($line =~ /our \$JAVASCRIPT_URL = '/) { $primary{'JAVASCRIPT_URL'} = demystify($line, 'JAVASCRIPT_URL'); next; } # CSS URL if ($line =~ /our \$CSS_URL = '/) { $primary{'CSS_URL'} = demystify($line, 'CSS_URL'); next; } # SSI URL if ($line =~ /our \$SSI_URL = '/) { $primary{'SSI_URL'} = demystify($line, 'SSI_URL'); next; } # Image URL if ($line =~ /our \$IMAGE_URL = '/) { $primary{'IMAGE_URL'} = demystify($line, 'IMAGE_URL'); next; } # SSI segments if ($line =~ /our %SSI_PAGES = \(/) { $line =~ s/^\s*//; $line =~ s/our %SSI_PAGES = //; $line =~ s/;$//; $line =~ s/\(//g; $line =~ s/\)//g; $line =~ s/'//g; $line =~ s/,//g; my %ssi_segs = split(/ /, $line); $primary{'SSI_PAGES'} = \%ssi_segs; } # Index Directory if ($line =~ /our \$INDEX_DIR = '/) { $primary{'INDEX_DIR'} = demystify($line, 'INDEX_DIR'); next; } } close(CONFIG); open ('CONFIG', "+<${inc_value}/MyLibrary/$config_module"); return \%primary; } sub demystify { my $mod_line = shift; my $option = shift; $mod_line =~ s/^\s*//; $mod_line =~ s/our \$${option} = //; $mod_line =~ s/'//; $mod_line =~ s/';$//; return $mod_line; }