#!C:/perl/bin/perl.exe -w

# scan_for_img.pl
# Compare the the images called for in HTML files in a directory to the 
# contents of an images directory and reports per image file whether
# or not it is called in the HTML and, if it is, which files call 
# it and how many times they called it. Reports on screen and to a log
# file.

use strict;
use HTML::PullParser;

my $imageDir  = "L:/inetpub/www/images";
my $imageHttp = "http://www.thqcollective.com/images/";   # In case a src attribute uses an absolute path
my $scanDir   = "L:/inetpub/www";
my $scanFile  = "";
my $fileName  = "";
my $scanLog   = "C:/Astell-THQ/wkg/img_scan_log.txt";
my %imagesUsed; # This hash holds the name of each image file in the images dir
                # as a key. Each key initial has a value of "none", which means it
                # is not used. As HTML files are scanned, if the image is used, "none"
                # is replaced with a string that lists which HTML file it
                # is used in and how many times in that file it is used.
my %imagesMiss; # This hash is like the above, but for image files that are called 
                # for in the HTML but are missing in the images directory.


# Create the log.
open( LOG, ">$scanLog" )
   or die "ERROR: Could not open $scanLog $! \n";
print LOG "See the end of the log for the final results \n";

# Scan the images dir.
opendir( WKG, "$imageDir" )
   or die "ERROR: Could not open $imageDir: $! \n";

IMG: foreach ( readdir( WKG ) )
{
   $scanFile = $imageDir . "/$_";
   next IMG if ( not -f $scanFile );        # Skip everything but files.

   my $extDot = rindex( $scanFile, "." );   # Get the location of the extension dot.
   next IMG if ( $extDot == -1 );           # Skip extensionless files.

   my $extName = substr( $scanFile, $extDot );   # Get the extension.
   next IMG unless ( $extName eq ".gif" 
                     or $extName eq ".jpg" 
                     or $extName eq ".png" );    # Skip all except web graphic files.

   $imagesUsed{ "$_" } = "none";   # Use the name of the file as a key in the hash.
}

closedir( WKG )
   or warn "ERROR: Could not close $scanDir: $! \n";


# Scan the HTML dir.
opendir( WKG, "$scanDir" )
   or die "ERROR: Could not open $scanDir: $! \n";
print "Scanning $scanDir \n";

FILE: foreach ( readdir( WKG ) )
{
   print "Found $_ \n";
   $fileName = $_;                          # Remember the name outside of $_.
   $scanFile = $scanDir . "/$_";
   next FILE if ( not -f $scanFile );       # Skip everything but files.

   my $extDot = rindex( $scanFile, "." );   # Get the location of the extension dot.
   next FILE if ( $extDot == -1 );          # Skip extensionless files.

   my $extName = substr( $scanFile, $extDot );                       # Get the extension.
   next FILE unless ( $extName eq ".htm" or $extName eq ".html" );   # Skip non-HTML files.

   ScanForImgTags();   # Scan the HTML for image tags and record the results.
}

closedir( WKG )
   or warn "ERROR: Could not close $scanDir: $! \n";


# Final processing and output.
foreach ( keys %imagesUsed )
{
   if ( $imagesUsed{$_} eq "none" )
   {
      $imagesUsed{$_} = "   This file is not called for in the scanned HTML! \n";
   }
}

print "\nRESULTS: \n";
print LOG "\nRESULTS: \n";

foreach ( sort keys %imagesUsed )
{
   print "$_ \n" . "$imagesUsed{$_} \n";
   print LOG "$_ \n" . "$imagesUsed{$_} \n";
}

# Also output missing images if any.
if ( %imagesMiss )
{
   print "\nMISSING FILES CALLED FOR IN THE HTML: \n";
   print LOG "\nMISSING FILES CALLED FOR IN THE HTML: \n";

   foreach ( sort keys %imagesMiss )
   {
      print "$_ \n" . "$imagesMiss{$_} \n";
      print LOG "$_ \n" . "$imagesMiss{$_} \n";
   }
}

close( LOG )
   or warn "ERROR: Could not close $scanLog: $! \n";

print "Done \n\n";


sub ScanForImgTags
{
   my $parser = HTML::Parser->new;
   my ( $numSrc, $numFound, $srcFile, $token );
   my %fileImgs;   # Hash used by function to track img tags; data reformatted
                   # and dumped into %imagesUsed before function returns.

   $parser = HTML::PullParser->new( file  => $scanFile,
                                    start => '"< ", tagname, @attr',
                                    end   => '"get_token )
   {
      # print "@$token \n";   # Uncomment this line to print the array for each token.

      # This handles things when an image tag is found.
      if ( @$token[1] eq "img" )
      {
         $numFound += 1;
         my $length = @$token;
         if ( $length < 3 )
         {
            print "Found an odd img tag: @$token \nTag has no attributes? \n\n";
            print LOG "Found an odd img tag: @$token \nTag has no attributes? \n\n";
            next;
         }

         print "Found an img tag: @$token \n";
         print LOG "Found an img tag: @$token \n";
         
         $numSrc = 0;
         for ( my $i = 2; $i < $length; $i++ )
         {
            if ( @$token[$i] eq "src" )
            {
               $srcFile = @$token[$i+1];   # The next item after "src" will be the file (unless
                                           # the source attribute is ill-formed; not error checked).
               print "src is: $srcFile \n";
               print LOG "src is: $srcFile \n";
               $numSrc += 1;

               if ( $srcFile =~ m`^images/` or $srcFile =~ m`$imageHttp` )
               {
                  # Found a call to a file in the target images directory.
                  my $imgFile = substr( $srcFile, rindex( $srcFile, "/" ) + 1 );
                  $fileImgs{$imgFile} += 1;   # Count each use of the image file in the HTML file.
               }
            }
         }
         if ( $numSrc == 0 )
         {
            print "ERROR: Couldn't find a src attribute in the tag! \n";
            print LOG "ERROR: Couldn't find a src attribute in the tag! \n";
         } elsif ( $numSrc > 1 )
         {
            print "ERROR: Found multiple src attributes in the tag! \n";
            print LOG "ERROR: Found multiple src attributes in the tag! \n";
         }

      }
   }
   print LOG "*** Number of image tags found in this file: $numFound *** \n\n";

   # Record results of HTML scan into %imagesUsed or %imagesMiss.
   foreach ( keys %fileImgs )
   {
      if ( exists $imagesUsed{$_} )
      {
         $imagesUsed{$_} = "" if ( $imagesUsed{$_} eq "none" );
         $imagesUsed{$_} .= "   $fileName uses it this many times: $fileImgs{$_} \n";
      } else
      {
         $imagesMiss{$_} .= "   $fileName uses it this many times: $fileImgs{$_} \n";
      }
   }
}