#!/usr/bin/perl #----------------------------------------------------------------------------- # GraphGoogleChartApi AWStats plugin # Allow AWStats to replace bar graphs with a Google Graph image #----------------------------------------------------------------------------- # Perl Required Modules: None #----------------------------------------------------------------------------- # # Changelog # # 1.0 - Initial release by george@dynapres.nl # 1.1 - Changed scaling: making it independent of chart series # 1.2 - Added pie charts, visualization hook, map and axis labels by Chris Larsen # <----- # ENTER HERE THE USE COMMAND FOR ALL REQUIRED PERL MODULES # -----> #use strict; no strict "refs"; #----------------------------------------------------------------------------- # PLUGIN VARIABLES #----------------------------------------------------------------------------- # <----- # ENTER HERE THE MINIMUM AWSTATS VERSION REQUIRED BY YOUR PLUGIN # AND THE NAME OF ALL FUNCTIONS THE PLUGIN MANAGE. my $PluginNeedAWStatsVersion = "7.0"; my $PluginHooksFunctions = "Init ShowGraph AddHTMLHeader"; my $PluginName = "graphgooglechartapi"; my $ChartProtocol = "https://"; my $ChartURI = "chart.googleapis.com/chart?"; # Don't put the HTTP part here! my $ChartIndex = 0; my $title; my $type; my $imagewidth = 640; # maximum image width. my $imageratio = .25; # Height is defaulted to 25% of width my $pieratio = .20; # Height for pie charts should be different my $mapratio = .62; # Height for maps is different my $labellength; my @blocklabel = (); my @vallabel = (); my @valcolor = (); my @valmax = (); my @valtotal = (); my @valaverage = (); my @valdata = (); # -----> # <----- # IF YOUR PLUGIN NEED GLOBAL VARIABLES, THEY MUST BE DECLARED HERE. use vars qw/ $DirClasses $URLIndex /; # -----> #----------------------------------------------------------------------------- # PLUGIN FUNCTION: Init_pluginname #----------------------------------------------------------------------------- sub Init_graphgooglechartapi { my $InitParams = shift; my $checkversion = &Check_Plugin_Version($PluginNeedAWStatsVersion); # <----- # ENTER HERE CODE TO DO INIT PLUGIN ACTIONS $DirClasses = $InitParams; # -----> $title = ""; $type = ""; $labellength=2; $ChartIndex = -1; return ($checkversion?$checkversion:"$PluginHooksFunctions"); } #------------------------------------------------------- # PLUGIN FUNCTION: ShowGraph_pluginname # UNIQUE: YES (Only one plugin using this function can be loaded) # Prints the proper chart depending on the $type provided # Parameters: $title $type $imagewidth \@blocklabel,\@vallabel,\@valcolor,\@valmax,\@valtotal # Input: None # Output: HTML code for awgraphapplet insertion # Return: 0 OK, 1 Error #------------------------------------------------------- sub ShowGraph_graphgooglechartapi() { $title = shift; $type = shift; $imagewidth = shift || 640; $blocklabel = shift; $vallabel = shift; $valcolor = shift; $valmax = shift; $valtotal = shift; $valaverage = shift; $valdata = shift; # check width if ($imagewidth < 1){$imagewidth=640;} if ($type eq 'month') { $labellength=3; print Get_Img_Tag(Graph_Monthly(), $title); } elsif ($type eq 'daysofmonth') { $labellength=2; print Get_Img_Tag(Graph_Daily(), $title); } elsif ($type eq 'daysofweek') { $labellength=3; print Get_Img_Tag(Graph_Weekly(), $title); } elsif ($type eq 'hours') { $labellength=2; print Get_Img_Tag(Graph_Hourly(), $title); } elsif ($type eq 'cluster'){ $labellength=32; print Get_Img_Tag(Graph_Pie(), $title); } elsif ($type eq 'filetypes'){ $labellength=4; print Get_Img_Tag(Graph_Pie(), $title); } elsif ($type eq 'httpstatus'){ $labellength=4; print Get_Img_Tag(Graph_Pie(), $title); } elsif ($type eq 'browsers'){ $labellength=32; print Get_Img_Tag(Graph_Pie(), $title); } elsif ($type eq 'downloads'){ $labellength=32; print Get_Img_Tag(Graph_Pie(), $title); } elsif ($type eq 'pages'){ $labellength=32; print Get_Img_Tag(Graph_Pie(), $title); } elsif ($type eq 'oss'){ $labellength=32; print Get_Img_Tag(Graph_Pie(), $title); } elsif ($type eq 'hosts'){ $labellength=32; print Get_Img_Tag(Graph_Pie(), $title); } elsif ($type eq 'countries_map'){ print Chart_Map(); } else { debug("Unknown type parameter in ShowGraph_graphgooglechartapi function: $title",1); #error("Unknown type parameter in ShowGraph_graphgooglechartapi function"); } return 0; } #------------------------------------------------------- # PLUGIN FUNCTION: AddHTMLHeader_pluginname # UNIQUE: NO # Prints javascript includes for Google Visualizations # Parameters: None # Input: None # Output: HTML code for Google Visualizations # Return: 0 OK, 1 Error #------------------------------------------------------- sub AddHTMLHeader_graphgooglechartapi(){ print "\n"; } #------------------------------------------------------- # PLUGIN FUNCTION: Graph_Monthly # Prints the image code to display a column chart of monthly usage # Parameters: None # Input: None # Output: HTML code to print a chart # Return: 0 OK, 1 Error #------------------------------------------------------- sub Graph_Monthly(){ my $chxt = "chxt="; my $chxl = "chxl="; my $chxs = "chxs="; my $chco = "chco="; my $chg = "chg="; my $chs = "chs="; my $cht = "cht=bvg"; my $chd = "chd=t:"; my $cba = "chbh=a"; # shows the whole month my $graphwidth = $imagewidth; my $graphheight = int ($imagewidth * $imageratio); # round max values foreach my $i(0..(scalar @$valmax)){ @$valmax[$i] = Round_Up(@$valmax[$i]); } # setup axis $chxt .= "x,y,y,r"; # add an x for years # get the month labels $chxl .= "0:|"; $chxl .= Get_Labels(); # get the hits/pages max $chxl .= "1:|0|".Get_Suffixed((@$valmax[0]/2),0)."|".Get_Suffixed(@$valmax[0],0)."|"; # get the visitors/pages max $chxl .= "2:|0|".Get_Suffixed((@$valmax[2]/2),0)."|".Get_Suffixed(@$valmax[2],0)."|"; # get bytes $chxl .= "3:|0|".Get_Suffixed((@$valmax[4]/2),1)."|".Get_Suffixed(@$valmax[4],1); # TODO add the year at the start and end # set the axis colors $chxs .= "1,".@$valcolor[0]."|2,".@$valcolor[2]."|3,".@$valcolor[4]; # dump colors foreach my $i(0..(scalar @$valcolor)){ $chco .= @$valcolor[$i]; if ($i < (scalar @$valcolor)-1){ $chco .= ",";} } # grid lines $chg .= "0,50"; # size $chs .= $graphwidth."x".$graphheight; # finally get the data $chd .= Get_Column_Data(); # string and dump return "$cht&$chxl&$chxt&$chxs&$chco&$chg&$chs&$chd&$cba"; } #------------------------------------------------------- # PLUGIN FUNCTION: Graph_Daily # Prints the image code to display a column chart of daily usage # Parameters: None # Input: None # Output: HTML code to print a chart # Return: 0 OK, 1 Error #------------------------------------------------------- sub Graph_Daily(){ my $chxt = "chxt="; my $chxl = "chxl="; my $chxs = "chxs="; my $chco = "chco="; my $chg = "chg="; my $chs = "chs="; my $cht = "cht=bvg"; my $chd = "chd=t:"; my $cba = "chbh=a"; # shows the whole month my $graphwidth = $imagewidth; my $graphheight = int ($imagewidth * $imageratio); # round max values foreach my $i(0..(scalar @$valmax)){ @$valmax[$i] = Round_Up(@$valmax[$i]); } # setup axis $chxt .= "x,y,y,r"; # add an x for years # setup axis labels # get day labels $chxl .= "0:|"; $chxl .= Get_Labels(); # get the hits/pages max $chxl .= "1:|0|".Get_Suffixed((@$valmax[0]/2),0)."|".Get_Suffixed(@$valmax[0],0)."|"; # get the visitors/pages max $chxl .= "2:|0|".Get_Suffixed((@$valmax[1]/2),0)."|".Get_Suffixed(@$valmax[1],0)."|"; # get bytes $chxl .= "3:|0|".Get_Suffixed((@$valmax[3]/2),1)."|".Get_Suffixed(@$valmax[3],1); # TODO month name # set the axis colors $chxs .= "1,".@$valcolor[0]."|2,".@$valcolor[1]."|3,".@$valcolor[3]; # dump colors foreach my $i(0..(scalar @$valcolor)){ $chco .= @$valcolor[$i]; if ($i < (scalar @$valcolor)-1){ $chco .= ",";} } # grid lines $chg .= "0,50"; # size $chs .= $graphwidth."x".$graphheight; # finally get the data $chd .= Get_Column_Data(); # string and dump return "$cht&$chxl&$chxt&$chxs&$chco&$chg&$chs&$chd&$cba"; } #------------------------------------------------------- # PLUGIN FUNCTION: Graph_Weekly # Prints the image code to display a column chart of weekly usage # Parameters: None # Input: None # Output: HTML code to print a chart # Return: 0 OK, 1 Error #------------------------------------------------------- sub Graph_Weekly(){ my $chxt = "chxt="; my $chxl = "chxl="; my $chxs = "chxs="; my $chco = "chco="; my $chg = "chg="; my $chs = "chs="; my $cht = "cht=bvg"; my $chd = "chd=t:"; my $cba = "chbh=a"; # shows the whole month my $graphwidth = int ($imagewidth * .75); # to maintain old look/ratio, reduce width of the weekly my $graphheight = int ($imagewidth * $imageratio); # round max values foreach my $i(0..(scalar @$valmax)){ @$valmax[$i] = Round_Up(@$valmax[$i]); } # setup axis $chxt .= "x,y,y,r"; # add an x for years # setup axis labels # get the day labels $chxl .= "0:|"; $chxl .= Get_Labels(); # get the hits/pages max $chxl .= "1:|0|".Get_Suffixed((@$valmax[0]/2),0)."|".Get_Suffixed(@$valmax[0],0)."|"; # get the visitors/pages max $chxl .= "2:|0|".Get_Suffixed((@$valmax[1]/2),0)."|".Get_Suffixed(@$valmax[1],0)."|"; # get bytes $chxl .= "3:|0|".Get_Suffixed((@$valmax[2]/2),1)."|".Get_Suffixed(@$valmax[2],1); # set the axis colors $chxs .= "1,".@$valcolor[0]."|2,".@$valcolor[1]."|3,".@$valcolor[2]; # dump colors foreach my $i(0..(scalar @$valcolor)){ $chco .= @$valcolor[$i]; if ($i < (scalar @$valcolor)-1){ $chco .= ",";} } # grid lines $chg .= "0,50"; # size $chs .= $graphwidth."x".$graphheight; # finally get the data $chd .= Get_Column_Data(); # string and dump return "$cht&$chxl&$chxt&$chxs&$chco&$chg&$chs&$chd&$cba"; } #------------------------------------------------------- # PLUGIN FUNCTION: Graph_Hourly # Prints the image code to display a column chart of hourly usage # Parameters: None # Input: None # Output: HTML code to print a chart # Return: 0 OK, 1 Error #------------------------------------------------------- sub Graph_Hourly(){ my $chxt = "chxt="; my $chxl = "chxl="; my $chxs = "chxs="; my $chco = "chco="; my $chg = "chg="; my $chs = "chs="; my $cht = "cht=bvg"; my $chd = "chd=t:"; my $cba = "chbh=a"; # shows the whole month my $graphwidth = $imagewidth; my $graphheight = int ($imagewidth * $imageratio); # round max values foreach my $i(0..(scalar @$valmax - 1)){ @$valmax[$i] = Round_Up(@$valmax[$i]); } # setup axis $chxt .= "x,y,y,r"; # add an x for years # setup axis labels $chxl .= "0:|"; $chxl .= Get_Labels(); # get the hits/pages max $chxl .= "1:|0|".Get_Suffixed((@$valmax[0]/2),0)."|".Get_Suffixed(@$valmax[0],0)."|"; # get the visitors/pages max $chxl .= "2:|0|".Get_Suffixed((@$valmax[1]/2),0)."|".Get_Suffixed(@$valmax[1],0)."|"; # get bytes $chxl .= "3:|0|".Get_Suffixed((@$valmax[2]/2),1)."|".Get_Suffixed(@$valmax[2],1); # TODO years # set the axis colors $chxs .= "1,".@$valcolor[0]."|2,".@$valcolor[1]."|3,".@$valcolor[2]; # dump colors foreach my $i(0..(scalar @$valcolor)){ $chco .= @$valcolor[$i]; if ($i < (scalar @$valcolor)-1){ $chco .= ",";} } # grid lines $chg .= "0,50"; # size $chs .= $graphwidth."x".$graphheight; # finally get the data $chd .= Get_Column_Data(); # string and dump return "$cht&$chxl&$chxt&$chxs&$chco&$chg&$chs&$chd&$cba"; } #------------------------------------------------------- # PLUGIN FUNCTION: Graph_Pie # Prints the image code to display a pie chart of the provided data # Parameters: None # Input: None # Output: HTML code to print a chart # Return: 0 OK, 1 Error #------------------------------------------------------- sub Graph_Pie(){ my $chl = "chl="; my $chs = "chs="; my $chco = "chco="; my $cht = "cht=p3"; my $chd = "chd=t:"; my $graphwidth = $imagewidth; my $graphheight = int ($imagewidth * $pieratio); # get labels $chl .= Get_Labels(); # get data, just read off the array for however many labels we have foreach my $i (0..((scalar @$blocklabel)-1)) { $chd .= int(@$valdata[$i]); $chd .= ($i < ((scalar @$blocklabel)-1) ? "," : ""); } # get color, just the first color passed $chco .= @$valcolor[0]; # set size $chs .= $graphwidth."x".$graphheight; return "$cht&$chs&$chco&$chl&$chd"; } #------------------------------------------------------- # PLUGIN FUNCTION: Chart_Map # Prints a Javascript and DIV tag to display a Google Visualization GeoMap # that uses the Flash plugin to display a map of the world shaded to reflect # the provided data # Parameters: None # Input: None # Output: Javascript and DIV tag # Return: 0 OK, 1 Error #------------------------------------------------------- sub Chart_Map(){ my $graphwidth = $imagewidth; my $graphheight = int ($imagewidth * $mapratio); # Assume we've already included the proper headers so just call our script inline print "\n\n"; # print the div tag that will contain the map print "
\n"; return; } #------------------------------------------------------- # PLUGIN FUNCTION: Get_Column_Data # Loops through the data array and prints a CHD string to send to a Google # chart via the API # Parameters: None # Input: @valcolor, @blocklabel, @valdata, @valmax # Output: None # Return: A pipe delimited string of data. REQUIRES the "chd=t:" prepended #------------------------------------------------------- # Returns a string with the CHD data sub Get_Column_Data(){ my $chd = ""; # use the # of colors to determine how many values we have $x= scalar @$valcolor; for ($serie = 0; $serie <= $x; $serie++) { foreach my $j (1.. (scalar @$blocklabel)) { if ($j > 1) { $chd .= ","; } $val = @$valdata[($j-1)*$x+$serie]; # convert our values to a percent of max $chd .= (@$valmax[$serie] > 0 ? int(($val / Round_Up(@$valmax[$serie])) * 100) : 0); } if ($serie < $x) { $chd .= "|"; } } # return return $chd; } #------------------------------------------------------- # PLUGIN FUNCTION: Get_Labels # Returns a CHXL string with labels to send to the Google chart API. Long labels # are shortened to $labellength # TODO - better shortening method instead of just lopping off the end of strings # Parameters: None # Input: @blocklabel, $labellength # Output: None # Return: A pipe delimited string of labels. REQUIRES the "chxl=" prepended #------------------------------------------------------- sub Get_Labels(){ my $chxl = ""; foreach my $i (1..(scalar @$blocklabel)) { $temp = @$blocklabel[$i-1]; if (length($temp) > $labellength){ $temp = (substr($temp,0,$labellength)); } $chxl .= "$temp|"; } $chxl =~ s/&//; return $chxl; } #------------------------------------------------------- # PLUGIN FUNCTION: Round_Up # Rounds a number up to the next most significant digit, i.e. 1234 becomes 2000 # Useful for getting the max values of our graph # Parameters: $num # Input: None # Output: None # Return: The rounded number #------------------------------------------------------- sub Round_Up(){ my $num = shift; $num = int($num); if ($num < 1){ return $num; } # under 100, just increment and dump if ($num < 100){return $num++; } $i = int(substr($num,0,2))+1; # pad with 0s $l = length($i); while ($l<(length($num))){ $i .= "0"; $l++; } return $i; } #------------------------------------------------------- # PLUGIN FUNCTION: Get_Suffixed # Converts a number for axis labels and appends the scientific notation suffix # or proper size in bytes # Parameters: $num # Input: @Message array from AWStats # Output: None # Return: A number with suffix, i.e. 400 MB or 200 K #------------------------------------------------------- sub Get_Suffixed(){ my $num = shift || 0; my $isbytes = shift || 0; my $float = 0; if ( $num >= ( 1 << 30 ) ) { $float = (split(/\./, $num / 1000000000))[1]; if ($float){ return sprintf( "%.1f", $num / 1000000000 ) . ($isbytes ? " $Message[110]" : " B"); }else{ return sprintf( "%.0f", $num / 1000000000 ) . ($isbytes ? " $Message[110]" : " B"); } } if ( $num >= ( 1 << 20 ) ) { $float = (split(/\./, $num / 1000000))[1]; if ($float){ return sprintf( "%.1f", $num / 1000000 ) . ($isbytes ? " $Message[109]" : " M"); }else{ return sprintf( "%.0f", $num / 1000000 ) . ($isbytes ? " $Message[109]" : " M"); } } if ( $num >= ( 1 << 10 ) ) { $float = (split(/\./, $num / 1000))[1]; if ($float){ return sprintf( "%.1f", $num / 1000 ) . ($isbytes ? " $Message[108]" : " K"); }else{ return sprintf( "%.0f", $num / 1000 ) . ($isbytes ? " $Message[108]" : " K"); } } return int($num); } #------------------------------------------------------- # PLUGIN FUNCTION: Get_Img_Tag # Builds the full IMG tag to place in HTML that will call the Google Charts API # Parameters: $params, $title # Input: $ChartProtocol, $ChartURI, $ChartIndex # Output: None # Return: An HTML IMG tag #------------------------------------------------------- sub Get_Img_Tag(){ my $params = shift || ""; my $title = shift || ""; my $tag = "= 9 ? 0 : $ChartIndex + 1); $tag .= $params; $tag .= "\" alt=\"$title\"/>"; } 1; # Do not remove this line