#!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 => '"", tagname' );
print "Scanning $scanFile \n";
print LOG "$scanFile \n";
$numFound = 0;
while ( $token = $parser->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";
}
}
}