#! /usr/bin/perl # # Purpose: # FlowTracker_Group.cgi is invoked by FlowTracker_Main.cgi to # collect information from the user to build a Group Tracking. # # Description: # The script responds to an HTML form from the user in order to collect # information taht will control the building of a group including, # component trackings, colors, and placements about teh x-axis. # # Input arguments (received from the form): # Name Description # ----------------------------------------------------------------------- # tracking_label Label used for identifying Tracking filter and HTML file # general_comment Useful for explaining a particular set of Tracking graphs # # Modification history: # Author Date Vers. Description # ----------------------------------------------------------------------- # J. Loiacono 02/14/2007 3.2 Original version # #$Author$ #$Date$ #$Header$ # ########################################################################### # # BEGIN EXECUTABLE STATEMENTS # use FlowViewer_Configuration; use FlowViewer_Utilities; use RRDs; if ($debug_group eq "Y") { open (DEBUG,">$work_directory/DEBUG_GROUP"); } # Retrieve input parameters from CGI form invocation (POST) read(STDIN, $buffer, $ENV{'CONTENT_LENGTH'}); @pairs = split(/&/, $buffer); foreach $pair (@pairs) { ($name, $value) = split(/=/, $pair); $value =~ tr/+/ /; $value =~ s/%([a-fA-F0-9][a-fA-F0-9])/pack("C",hex($1))/eg; $FORM{$name} = $value; } $action = $FORM{action}; $tracking_label = $FORM{tracking_label}; $general_comment = $FORM{general_comment}; $revision_comment = $FORM{revision_comment}; $notate_graphs = $FORM{notate_graphs}; $invoke_method = "CGI"; # Retrieve input parameters from initial FlowTracker_Main.cgi invocation if ($ARGV[0] ne "") { $invoke_method = "Inline"; $tracking_info = $ARGV[0]; $tracking_info =~ s/~/ /g; ($action,$tracking_label,$general_comment) = split(/\+/,$tracking_info); if ($action eq "Solicit") { $action = "Solicit Revision"; } } if ($ARGV[1] ne "") { $tracking_label = $ARGV[1]; $tracking_label =~ s/\\//g; $tracking_label =~ s/~/ /g; } $tracking_file = $tracking_label; $tracking_file =~ s/^\s+//; $tracking_file =~ s/\s+$//; $tracking_file =~ s/\&/-/g; $tracking_file =~ s/\//-/g; $tracking_file =~ s/\(/-/g; $tracking_file =~ s/\)/-/g; $tracking_file =~ s/\./-/g; $tracking_file =~ s/\s+/_/g; $tracking_file =~ tr/[A-Z]/[a-z]/; $group_file = $filter_directory ."/". $tracking_file .".grp"; if ($debug_group eq "Y") { print DEBUG "In Flow_Tracker_Group.cgi ...\n"; print DEBUG " invoke method: $invoke_method\n"; print DEBUG " ARGV[0]: $ARGV[0]\n"; print DEBUG " ARGV[1]: $ARGV[1]\n"; print DEBUG " action: $action\n"; print DEBUG " tracking_info: $tracking_info\n"; print DEBUG " tracking_label: $tracking_label\n"; print DEBUG " tracking_file: $tracking_file\n"; print DEBUG "general_comment: $general_comment\n"; print DEBUG " tracking_file: $tracking_file\n"; } # Create the GROUPS directory if it doesn't exist $groups_directory = "$tracker_directory/GROUPS"; if (!-e $groups_directory) { mkdir $groups_directory, $html_dir_perms || die "cannot mkdir $groups_directory: $!"; chmod $html_dir_perms, $groups_directory; } # Load the colors $colors_file = "$cgi_bin_directory/FlowGrapher_Colors"; open (COLORS,"<$colors_file") || die "Can't open colors file; $colors_file\n"; while () { chop; ($red,$green,$blue,$color_1,$color_2) = split(/\s+/); $color_name = $color_1; if ($color_2 ne "") { $color_name = $color_1 . " " . $color_2; } $R = &dec2hex($red); if (length($R) < 2) { $R = "0" . $R; } $G = &dec2hex($green); if (length($G) < 2) { $G = "0" . $G; } $B = &dec2hex($blue); if (length($B) < 2) { $B = "0" . $B; } $hex_colors{$color_name} = $R . $G . $B; } $hex_colors{"standard"} = $rrd_area; sub dec2hex($) { return sprintf("%lx", $_[0]) } # Retrieve existing group information for revision if ($action eq "Solicit Revision") { open (GROUP,"<$group_file"); while () { chop; $key = substr($_,0,8); if ($key eq " input: ") { ($input,$field,$field_value) = split(/: /); if ($field eq "general_comment") { $general_comment = $field_value; } } } close (GROUP); } # Revise Group Comments if ($action eq "Revise Group Comments") { open (GROUP,"<$group_file"); while () { $next_line = $_; $key = substr($_,0,8); if ($key eq " input: ") { ($input,$field,$field_value) = split(/: /); if ($field eq "general_comment") { $next_line = " input: general_comment: $general_comment\n"; } if ($field eq "revision") { $revision_num++; } } push (@group_lines,$next_line); } close (GROUP); open (GROUP,">$group_file"); foreach $input_line (@group_lines) { print GROUP $input_line; } close (GROUP); if (($revision_comment ne "") && ($revision_num < 3)) { open (GROUP,">>$group_file"); $revision_date = time - 60; print GROUP " input: revision: $notate_graphs|$revision_date|$revision_comment\n"; close (GROUP); } chmod $filter_file_perms, $group_file; } # Add a new component if ($action eq "Add this Component") { $add_label = $FORM{add_label}; $add_location = $FORM{add_location}; $add_color = $FORM{add_color}; open (GROUP,"<$group_file"); @group_lines = ; close (GROUP); foreach $group_line (@group_lines) { if ($group_line =~ / input:/) { push (@input_lines,$group_line); } else { push (@components,$group_line); } } $largest_above = 100; $largest_below = 200; foreach $component (@components) { ($component_position,$component_label,$component_color) = split(/\^/,$component); if (($component_position<200) && ($component_position>$largest_above)) { $largest_above = $component_position; } if (($component_position>200) && ($component_position>$largest_below)) { $largest_below = $component_position; } if ($component_color =~ /auto blue/) { $next_blue = substr($component_color,9,1); if ($component_position < 200) { if ($next_blue > $largest_blue_above) { $largest_blue_above = $next_blue; } } if ($component_position > 200) { if ($next_blue > $largest_blue_below) { $largest_blue_below = $next_blue; } } } if ($component_color =~ /auto red/) { $next_red = substr($component_color,8,1); if ($component_position < 200) { if ($next_red > $largest_red_above) { $largest_red_above = $next_red; } } if ($component_position > 200) { if ($next_red > $largest_red_below) { $largest_red_below = $next_red; } } } if ($component_color =~ /auto green/) { $next_green = substr($component_color,10,1); if ($component_position < 200) { if ($next_green > $largest_green_above) { $largest_green_above = $next_green; } } if ($component_position > 200) { if ($next_green > $largest_green_below) { $largest_green_below = $next_green; } } } } $add_color_value = $add_color; $add_color =~ s/_/ /; if (($add_location eq "above") && ($add_color eq "auto blue")) { $add_color .= $largest_blue_above + 1; } if (($add_location eq "above") && ($add_color eq "auto red")) { $add_color .= $largest_red_above + 1; } if (($add_location eq "above") && ($add_color eq "auto green")) { $add_color .= $largest_green_above + 1; } if (($add_location eq "below") && ($add_color eq "auto blue")) { $add_color .= $largest_blue_below + 1; } if (($add_location eq "below") && ($add_color eq "auto red")) { $add_color .= $largest_red_below + 1; } if (($add_location eq "below") && ($add_color eq "auto green")) { $add_color .= $largest_green_below + 1; } $add_component = $add_label ."^". $add_color ."\n";; # Determine new position if (($add_location eq "above") && ($largest_above == 100)) { $add_component = $largest_above+1 ."^". $add_component; push (@new_group,$add_component); } foreach $component (@components) { ($component_position,$component_label,$component_color) = split(/\^/,$component); push (@new_group,$component); if (($add_location eq "above") && ($component_position == $largest_above)) { $add_component = $largest_above+1 ."^". $add_component; push (@new_group,$add_component); } if (($add_location eq "below") && ($component_position == $largest_below)) { $add_component = $largest_below+1 ."^". $add_component; push (@new_group,$add_component); } } if (($add_location eq "below") && ($largest_below == 200)) { $add_component = $largest_below+1 ."^". $add_component; push (@new_group,$add_component); } # Rewrite group file open (GROUP,">$group_file"); foreach $component (@new_group) { print GROUP $component; } foreach $input_line (@input_lines) { print GROUP $input_line; } close (GROUP); chmod $filter_file_perms, $group_file; } # Adjust the group if ($action eq "Adjust the Group") { open (GROUP,"<$group_file"); @group_lines = ; close (GROUP); foreach $group_line (@group_lines) { if ($group_line =~ / input:/) { push (@input_lines,$group_line); } else { push (@components,$group_line); } } foreach $component (@components) { $num_components++; chop $component; ($component_position,$component_label,$component_color) = split(/\^/,$component); $new_color = "new_color_" . $component_position; $component_color = $FORM{$new_color}; $component_color =~ s/_/ /; $component = $component_position ."^". $component_label ."^". $component_color; push (@adjusted_components,$component); $component_data = $component_label ."^". $component_color; $placements{$component_position} = $component_data; if (($component_position<200) && ($component_position>$largest_above)) { $largest_above = $component_position; } if (($component_position>200) && ($component_position>$largest_below)) { $largest_below = $component_position; } } foreach $position (keys (%placements)) { ($component_label,$component_color) = split(/\^/,$placements{$position}); $new_position = "new_position_" . $position; $move_component = $FORM{$new_position}; if ($move_component eq "move_away") { if (($position == $largest_above) || ($position == $largest_below)) { next; } $temp_component = $placements{$position+1}; $placements{$position+1} = $placements{$position}; $placements{$position} = $temp_component; } elsif ($move_component eq "move_closer") { if (($position == 101) || ($position == 201)) { next; } $temp_component = $placements{$position-1}; $placements{$position-1} = $placements{$position}; $placements{$position} = $temp_component; } elsif ($move_component eq "remove") { if ($position < 200) { if ($position == $largest_above) { delete $placements{$position}; $largest_above--; next; } for ($i=$position+1;$i<=$largest_above;$i++) { $placements{$i-1} = $placements{$i}; } delete $placements{$largest_above}; $largest_above--; } if ($position > 200) { if ($position == $largest_below) { delete $placements{$position}; $largest_below--; next; } for ($i=$position+1;$i<=$largest_below;$i++) { $placements{$i-1} = $placements{$i}; } delete $placements{$largest_below}; $largest_below--; } } } @sorted_keys = sort keys(%placements); foreach $position (@sorted_keys) { $component = $position ."^". $placements{$position}; push (@sorted_components,$component); } open (GROUP,">$group_file"); foreach $component (@sorted_components) { print GROUP "$component\n"; } foreach $input_line (@input_lines) { print GROUP $input_line; } close (GROUP); chmod $filter_file_perms, $group_file; } print "Content-type:text/html\n\n"; print ""; print ""; print ""; print ""; print "FlowTracker $version Group Tracking"; print "
\n";
print "";
print "
"; print "\n"; print ""; print "
"; print "   "; print ""; print "$tracking_label\n"; print "
"; $end_rrd = time; $start_rrd = $end_rrd - 86400; # Gather existing components (if any) of this group $num_components = 0; $first_below = 1; open (GROUP,"<$group_file") || die "Can't open group file: $group_file"; while () { $num_components++; chop; if (/ input:/) { $num_components--; ($input,$field,$field_value) = split(/: /); if ($field eq "revision") { ($notate_graphs,$revision_date,$revision_comment) = split(/\|/,$field_value); $revision_date_out = epoch_to_date($revision_date,"LOCAL"); $revision_date_out =~ s/:/\\:/g; if ($notate_graphs eq "Y") { if ($vrule_1 eq "") { $revision_date = $start_rrd + 21600; $vrule_1 = " VRULE:$revision_date#$rrd_vrule_color:\"$revision_date_out\\: $revision_comment\\n\""; next; } elsif ($vrule_2 eq "") { $revision_date = $start_rrd + 43200; $vrule_2 = " VRULE:$revision_date#$rrd_vrule_color:\"$revision_date_out\\: $revision_comment\\n\""; next; } elsif ($vrule_3 eq "") { $revision_date = $start_rrd + 64800; $vrule_3 = " VRULE:$revision_date#$rrd_vrule_color:\"$revision_date_out\\: $revision_comment\\n\""; next; } } } next; } ($component_position,$component_label,$component_color) = split(/\^/,$_); $component_rrd = "$work_directory/COMPONENT_SAMPLE$num_components.rrd"; $DEF_parameters .= "DEF:flowbits$num_components=$component_rrd:flowbits:AVERAGE "; $AREA_parameters .= "COMMENT:\" \" "; if ($component_position < 200) { $AREA_parameters .= "AREA:flowbits$num_components#$hex_colors{$component_color}:\"$component_label\\n\":STACK "; } elsif (($component_position >= 200) && ($first_below)) { $DEF_parameters .= "CDEF:flowbits_below$num_components=flowbits$num_components,-1,* "; $AREA_parameters .= "AREA:flowbits_below$num_components#$hex_colors{$component_color}:\"$component_label\\n\" "; $first_below = 0; } else { $DEF_parameters .= "CDEF:flowbits_below$num_components=flowbits$num_components,-1,* "; $AREA_parameters .= "AREA:flowbits_below$num_components#$hex_colors{$component_color}:\"$component_label\\n\":STACK "; } } # Generate Sample Graph from Sample RRDtool database $rm_command = "rm -rf $tracker_directory/GROUPS/*"; system($rm_command); $suffix = rand(); $suffix = int ($suffix * 100); $graph_file = "$tracker_directory/GROUPS/GROUP_SAMPLE$suffix.png"; $graph_file_link = "$tracker_short/GROUPS/GROUP_SAMPLE$suffix.png"; if ($num_components == 0) { $rrdtool_file = "$work_directory/COMPONENT_SAMPLE.rrd"; $rrdtool_command = "$rrdtool_bin_directory/rrdtool create $rrdtool_file ". "--step 300 ". "--start $start_rrd ". "DS:flowbits:GAUGE:600:U:U ". "RRA:AVERAGE:0.5:1:600 "; system($rrdtool_command); chmod $rrd_file_perms, $rrdtool_file; $DEF_parameters .= "DEF:flowbits0$num_components=$rrdtool_file:flowbits:AVERAGE "; $AREA_parameters .= "COMMENT:\" \" "; $AREA_parameters .= "AREA:flowbits0$num_components#FFFFFF::STACK "; } for ($i=1;$i<=$num_components;$i++) { $rrdtool_file = "$work_directory/COMPONENT_SAMPLE$i.rrd"; $rrdtool_command = "$rrdtool_bin_directory/rrdtool create $rrdtool_file ". "--step 300 ". "--start $start_rrd ". "DS:flowbits:GAUGE:600:U:U ". "RRA:AVERAGE:0.5:1:600 "; system($rrdtool_command); chmod $rrd_file_perms, $rrdtool_file; $num_point = 0; for ($j=1;$j<=4;$j++) { for ($k=-36;$k<36;$k++) { $num_point++; $next_time = $start_rrd + ($num_point * 300); $x = ($k / 36) * 3.14159; $sinx = sin ($x); $next_value = int(300000 + ($sinx * 30000)); RRDs::update ("$rrdtool_file","$next_time:$next_value"); $ERR=RRDs::error; if (($debug_group eq "Y") && ($ERR ne "")) { print DEBUG "RRDs ERR: $ERR\n"; } } } } $tracking_label_out = $tracking_label; $tracking_label =~ s/\s+$//; $tracking_label_out =~ s/\s+/_/g; $rrd_title = $tracking_label_out . "_Sample"; @graph_parameters = ('--title',"$rrd_title", '--start',$start_rrd, '--end',$end_rrd, '--width',$rrd_width, '--height',$rrd_height, '--interlace', '--vertical-label',"\"Bits per Second\"", $rrd_slope_mode, "--color=FONT#$rrd_font", "--color=BACK#$rrd_back", "--color=CANVAS#$rrd_canvas", "--color=GRID#$rrd_grid", "--color=MGRID#$rrd_mgrid", "--color=FRAME#$rrd_frame", "--color=SHADEA#$rrd_frame", "--color=SHADEB#$rrd_frame", '--lower-limit',$rrd_lower_limit, '--alt-autoscale', $DEF_parameters, "COMMENT:\"\\n\"", $AREA_parameters, "COMMENT:\"\\n\"", "COMMENT:\" \"", $vrule_1, "COMMENT:\" \"", $vrule_2, "COMMENT:\" \"", $vrule_3); $rrdgraph_command = "$rrdtool_bin_directory/rrdtool graph " . "$graph_file " . "@graph_parameters " . ">/dev/null"; system($rrdgraph_command); chmod $tracker_file_perms, $graph_file; print " \n"; print "
"; print "
\n"; 
print "
"; # Clean up temporary COMPONENT RRD files $cleanup_command = "rm $work_directory/COMPONENT_SAMPLE*"; system($cleanup_command); # Build list of existing trackings to select from print " Select an existing Tracking to be a component of this Group:\n\n\n"; print "
"; print " Select a Component: \n\n"; print " Place this Component: \n\n"; open (COLORS,"<$cgi_bin_directory/FlowGrapher_Colors"); print " Select a Color: \n\n\n"; print "
"; print "\n"; print " \;\n\n"; print "
"; print "
"; # List the components so that a user can modify them, their position, their order, or their color print " This group is composed of these components:\n\n\n"; print ""; open (GROUP,"<$group_file"); @components = ; close (GROUP); $num_components = 0; foreach $component (@components) { $num_components++; if ($component =~ / input:/) { $num_components--; next; } chop $component; ($component_position,$component_label,$component_color) = split(/\^/,$component); $component_parameter = $component_label; $component_parameter =~ s//~/g; $component_label_out = $component_label; $len_component = length($component_label); if ($len_component > 40) { $start_char = $len_component - 38; $component_label_out = substr($component_label_out,$start_char,38); $component_label_out = "..." . $component_label_out; } for ($i=$len_component;$i<=40;$i++) { $component_label_out .= " "; } $component_link = "$component_label_out"; $component_color_value = $component_color; $component_color_value =~ s/ /_/; $component_color_out = $component_color; $len_color = length($component_color); for ($i=$len_color;$i<=16;$i++) { $component_color_out .= " "; } $color_link = "$component_color_out"; $axis_position = substr($component_position,0,1); $stack_position = substr($component_position,1,2); if ($axis_position == 1) { $component_position_out = "Above "; } else { $component_position_out = "Below "; } $component_position_out .= $stack_position; $next_component = $component_position ."##". $component_position_out ."##". $component_link ."##". $color_link ."##". $component_color ."##". $component_color_value; if ($component_position < 200) { push (@upper_components,$next_component); } if ($component_position > 200) { push (@lower_components,$next_component); } } # Print out components that appear ABOVE the axis @reversed_uppers = reverse (@upper_components); foreach $upper_component (@reversed_uppers) { ($component_position,$component_position_out,$component_link,$color_link,$component_color,$component_color_value) = split(/##/,$upper_component); printf " %-40s %-8s %-16s", $component_link, $component_position_out, $color_link; $new_color = "new_color_" . $component_position; print "New Color: "; $new_position = "new_position_" . $component_position; print " Move: \n"; } # Print out components that appear BELOW the axis if (@lower_components) { print "
"; } foreach $lower_component (@lower_components) { ($component_position,$component_position_out,$component_link,$color_link,$component_color,$component_color_value) = split(/##/,$lower_component); printf " %-40s %-8s %-16s", $component_link, $component_position_out, $color_link; $new_color = "new_color_" . $component_position; print "New Color: "; $new_position = "new_position_" . $component_position; print " Move: \n"; } print "
"; print "
"; print "\n"; print " \;\n\n"; print "
"; print "
"; # List out current Comment and Revision input print ""; print " Change Comment or add a Revision Mark (Maximum three revisions):\n\n\n"; print " General Comment: "; print "\n\n"; $revision_comment = ""; print " Revision Comment: "; print "\n\n"; print " Notate Graphs:
(To notate graphs with time and description of revision)"; print "\n\n"; print "
"; print "\n"; print " \;\n\n"; print "\n"; print "
"; # Print Done button print "\n"; $done_link = "$FlowViewer_service://$FlowViewer_server$cgi_bin_short/FlowTracker.cgi"; print "
"; print "\n\n"; print "
"; print "
"; print "\n"; print "\n"; sub print_error { my ($error_text) = @_; $rm_command = "rm $filter_file"; system($rm_command); print ""; print ""; print ""; print "FlowTracker Error"; print "
\n"; print "

$error_text


"; print " Use browser \"bask\" key to preserve inputs for modification
"; print "
\n"; print "
"; print "
"; exit; }