File Coverage

blib/lib/WebServer/DirIndex.pm
Criterion Covered Total %
statement 33 33 100.0
branch n/a
condition n/a
subroutine 11 11 100.0
pod n/a
total 44 44 100.0


line stmt bran cond sub pod time code
1 1     1   150937 use strict;
  1         2  
  1         39  
2 1     1   5 use warnings;
  1         2  
  1         59  
3 1     1   724 use Feature::Compat::Class;
  1         496  
  1         5  
4 1     1   810 use WebServer::DirIndex::HTML;
  1         4  
  1         72  
5              
6             our $VERSION = '0.1.2';
7              
8             class WebServer::DirIndex {
9              
10 1     1   1119 use Path::Tiny;
  1         16769  
  1         76  
11 1     1   753 use HTTP::Date;
  1         5824  
  1         113  
12 1     1   576 use HTML::Escape qw(escape_html);
  1         977  
  1         72  
13 1     1   636 use MIME::Types;
  1         6048  
  1         55  
14 1     1   651 use URI::Escape;
  1         2233  
  1         92  
15 1     1   587 use WebServer::DirIndex::CSS;
  1         3  
  1         37  
16 1     1   576 use WebServer::DirIndex::File;
  1         4  
  1         853  
17              
18             my $mime_types = MIME::Types->new;
19              
20             field $dir :param;
21             field $dir_url :param;
22             field $icons :param = undef;
23             field $pretty :param = 0;
24             field $html_class :param = 'WebServer::DirIndex::HTML';
25             field $css_class :param = 'WebServer::DirIndex::CSS';
26             field $_html_obj;
27             field $_css_obj;
28             field @files;
29              
30             ADJUST {
31             $icons = 1 if !defined($icons) && $pretty; # pretty implies icons when unset
32             $icons //= 1; # default to enabled otherwise
33             $_html_obj = $html_class->new(icons => $icons);
34             $_css_obj = $css_class->new(pretty => $pretty);
35             @files = ( WebServer::DirIndex::File->parent_dir(
36             html_class => $html_class,
37             icons => $icons,
38             ) );
39              
40             my @children = map { $_->basename } path($dir)->children;
41              
42             for my $basename (sort { $a cmp $b } @children) {
43             my $file = "$dir/$basename";
44             my $url = $dir_url . $basename;
45              
46             my $is_dir = -d $file;
47             my @stat = stat $file;
48              
49             $url = join '/', map { uri_escape($_) } split m{/}, $url;
50              
51             if ($is_dir) {
52             $basename .= '/';
53             $url .= '/';
54             }
55              
56             my $type_obj = $is_dir ? undef : $mime_types->mimeTypeOf($file);
57             my $mime_type = $is_dir
58             ? 'directory'
59             : ($type_obj ? $type_obj->type : 'text/plain');
60              
61             push @files, WebServer::DirIndex::File->new(
62             url => $url,
63             name => $basename,
64             size => $stat[7],
65             mime_type => $mime_type,
66             mtime => HTTP::Date::time2str($stat[9]),
67             html_class => $html_class,
68             icons => $icons,
69             );
70             }
71             }
72              
73             method files { return @files }
74              
75             method to_html ($path_info) {
76             my $path = escape_html("Index of $path_info");
77             my $files_html = join "\n", map { $_->to_html } @files;
78             my $css = $_css_obj->css;
79             return sprintf $_html_obj->dir_html, $path, $css, $path, $files_html;
80             }
81             }
82              
83             1;
84              
85             __END__