1 package Treemap::Input::DirSlashS; 2 3 use 5.006; 4 use strict; 5 use warnings; 6 use Carp; 7 8 use File::Basename; 9 10 require Exporter; 11 require Treemap::Input; 12 13 our @ISA = qw( Treemap::Input Exporter ); 14 our @EXPORT_OK = ( ); 15 our @EXPORT = qw( ); 16 our $VERSION = '0.01'; 17 18 # ------------------------------------------ 19 # Methods: 20 # ------------------------------------------ 21 sub new 22 { 23 my $classname = shift; 24 my $self = $classname->SUPER::new( @_ ); # Call parent constructor 25 $self->_init( @_ ); # Initialize child variables 26 return $self; 27 } 28 29 sub _init 30 { 31 my $self = shift; 32 } 33 34 sub load 35 { 36 my $self = shift; 37 my( $filename ) = @_; 38 39 open( FH, $filename ) || die "Couldn't open $filename"; 40 41 # First we need to parse this nasty format, and turn it into something 42 # computable 43 my $data; 44 my $present_dir; 45 while( <FH> ) { 46 next if /^[\n\r]$/; # Skip blank lines 47 48 # Keep track of which directory we're in. 49 if ( /^[ ]+Directory of ([^\n\r]*)/ ) { 50 $present_dir = $1; 51 next; 52 } 53 # Find the number of bytes in this directory. 54 # This is also our end-of-record, so insert the present directory and 55 # it's size into our data structure. 56 # elsif( /File\(s\)[ ]+([0-9,]+) bytes/ ) { 57 # my $bytes = $1; 58 # my $path = $present_dir; 59 elsif ( /^([0-9]{2})\/([0-9]{2})\/([0-9]{4}).{10}[ ]+([0-9,]+) ([^\n\r]*)/ ) { 60 my $path = "$present_dir\\$5"; 61 my $bytes = $4; 62 $bytes =~ s/,//g; 63 my @dirs = split (/\\/, $path ); 64 my $code = "\$data->{kids}->{\"" . join("\"}->{kids}->{\"", @dirs ) . "\"}->{size} = \"$bytes\";"; 65 eval( $code ); 66 } 67 } 68 # Traverse the resultant tree and convert it into a treemap data structure 69 $self->{DATA} = $self->_TreemapForm( $data ); 70 $data = undef; 71 if ( $self->{DATA} ) { 72 return 1; 73 } 74 return 0; 75 } 76 77 sub _TreemapForm { 78 my $self = shift; 79 my( $data, $name ) = @_; 80 my $tree; 81 $tree->{size} = $data->{size} || 0; 82 $tree->{name} = $name || undef; 83 if ( $name =~ /\.(.{0,3})$/ && length($1) > 0 ) { 84 my ( $rr, $gg, $bb ) = split ( //, uc($1) ); 85 $rr = ord($rr); $gg = ord($gg); $bb = ord($bb); 86 $rr==47?$rr=0:$rr=($rr - 47) / 42 * 256; 87 $gg==47?$gg=0:$gg=($gg - 47) / 42 * 256; 88 $bb==47?$bb=0:$bb=($bb - 47) / 42 * 256; 89 $tree->{colour} = sprintf("#%2X%2X%2X", $rr, $gg, $bb ); 90 } else { 91 $tree->{colour} = "#FFFFFF"; 92 } 93 if ( defined($data->{kids}) ) { 94 my @kids = (); 95 foreach my $kid( keys(%{$data->{kids}}) ) { 96 push( @kids, $self->_TreemapForm( $data->{kids}->{$kid}, $kid ) ); 97 $tree->{size} += $kids[@kids-1]->{size}; 98 } 99 $tree->{children} = \@kids; 100 } 101 return $tree; 102 } 103 1; 104 105 __END__ 106 107 # ------------------------------------------ 108 # Documentation: 109 # ------------------------------------------ 110 111 =head1 NAME 112 113 =over 4 114 115 =item Treemap::Input::DirSlashS 116 117 Creates an input object with methods suitable for use with a Treemap object. 118 119 =back 4 120 121 =head1 SYNOPSIS 122 123 #!/usr/bin/perl -w 124 use Treemap::Input::DirSlashS; 125 126 my $dir = Treemap::Input::DirSlashS->new(); 127 $dir->load( "/some/dir" ); 128 129 =head1 DESCRIPTION 130 131 This class reads in a directory tree, and makes the data available for use to a 132 Treemap object. Colour is based the the mtime of the files. Rectangle areas 133 are based on the size of the directory contents / files. 134 135 =head1 METHODS 136 137 =over 4 138 139 =item new( FOLLOW_SYMLINKS => (1|undef) ) 140 141 Instantiate a new object 142 143 =item load( "filename.txt" ) 144 145 Load the output of "dir /s > filname.txt". 146 147 =back 4 148 149 =head1 SEE ALSO 150 151 L<Treemap::Input>, L<Treemap> 152 153 =head1 AUTHORS 154 155 Simon Ditner <simon@uc.org>, and Eric Maki <eric@uc.org> 156 157 =head1 LICENSE 158 159 This library is free software; you can redistribute it and/or modify it under 160 the same terms as Perl itself. 161 162 =cut