#!/usr/bin/perl
my $root_dir = 'D:/';
my $output_file = 'cd-contents.html';
my $file_icon = '
';
my $dir_icon = '
';
my $vol_icon = '
';
my @indents = (
'
',
'
',
'
',
'
'
);
my $html_head = <Folders & Files: $root_dir
Folders & Files: $root_dir
ENDOFHTML
my $html_foot = <
ENDOFHTML
######################################################################
use strict;
use File::Find;
use File::stat;
my (%files, %dirs);
find(\&learn_files, $root_dir);
my @data_output;
foreach (sort keys %dirs) {
my @indent = split(/\//, substr($_, length($root_dir) + 1));
push @data_output, [$#indent + 1, $vol_icon, $_,
'(' . fix_bytes($dirs{$_}{size} + 0) .
', ' . comma($dirs{$_}{files} + 0) . ' files' .
', ' . comma($dirs{$_}{subdirs} + 0) . ' folders)'];
if ($#indent > -1) {
$data_output[$#data_output][1] = $dir_icon;
$data_output[$#data_output][2] = $indent[$#indent];
}
foreach my $file (sort keys %{$files{$_}}) {
push @data_output, [$#indent + 2, $file_icon, $file,
'(' . fix_bytes($files{$_}{$file}) . ')'];
}
}
my @previous_lines;
for (my $x = $#data_output; $x > 0; $x--) {
for (my $y = 0; $y < $data_output[$x][0] - 1; $y++) {
if ($previous_lines[$y]) {
$data_output[$x][4] .= $indents[1];
} else {
$data_output[$x][4] .= $indents[0];
}
}
if ($data_output[$x][0] == $data_output[$x+1][0]) {
$data_output[$x][4] .= $indents[3];
} elsif ($data_output[$x][0] < $data_output[$x+1][0]) {
if ($previous_lines[$data_output[$x][0] - 1]) {
$data_output[$x][4] .= $indents[3];
} else {
$data_output[$x][4] .= $indents[2];
}
$#previous_lines = $data_output[$x][0] - 1;
} else {
$data_output[$x][4] .= $indents[2];
}
$previous_lines[$data_output[$x][0] - 1] = 1;
}
open(OUT, "> $output_file");
print OUT $html_head, "\n";
foreach (@data_output) {
print OUT $_->[4], $_->[1], $_->[2], ' ', $_->[3], "
\n";
}
print OUT $html_foot, "\n";
close(OUT);
######################################################################
sub learn_files {
if (-d) {
if ($_ ne '.') {
$dirs{$File::Find::dir}{subdirs}++;
add_up($File::Find::dir);
}
} else {
$dirs{$File::Find::dir}{files}++;
my $file_info = stat($File::Find::name);
$dirs{$File::Find::dir}{size} += $file_info->size;
$files{$File::Find::dir}{$_} = $file_info->size;
add_up($File::Find::dir, $file_info->size)
if ($File::Find::dir ne $root_dir);
}
}
sub add_up {
my $dir = substr($_[0], length($root_dir) + 1);
my $curr_dir = $root_dir;
foreach (split(/\//, $dir)) {
if ($_[1] eq '') {
$dirs{$curr_dir}{subdirs}++;
} else {
$dirs{$curr_dir}{files}++;
$dirs{$curr_dir}{size} += $_[1];
}
$curr_dir .= "/$_";
}
}
sub fix_bytes {
return comma(int($_[0] / 10737418.24) / 100) . ' GB' if ($_[0] > 1073741824);
return comma(int($_[0] / 10485.76) / 100) . ' MB' if ($_[0] > 1048576);
return comma(int($_[0] / 10.24) / 100) . ' KB' if ($_[0] > 1024);
return comma($_[0]) . ' bytes';
}
sub comma {
my $text = reverse $_[0];
$text =~ s/(\d\d\d)(?=\d)(?!\d*\.)/$1,/g;
return scalar reverse $text;
}