File Coverage

blib/lib/Dancer2/Plugin/Path/Class.pm
Criterion Covered Total %
statement 80 85 94.1
branch 14 22 63.6
condition n/a
subroutine 11 11 100.0
pod n/a
total 105 118 88.9


line stmt bran cond sub pod time code
1             package Dancer2::Plugin::Path::Class;
2              
3             # ABSTRACT: list a directory using Path::Class
4              
5 2     2   744672 use strict;
  2         5  
  2         53  
6 2     2   10 use warnings;
  2         3  
  2         83  
7              
8             our $VERSION = 0.05;
9              
10 2     2   1815 use Dancer2::Plugin;
  2         153250  
  2         21  
11 2     2   3649 use MIME::Types;
  2         9290  
  2         139  
12 2     2   1891 use Path::Class;
  2         79282  
  2         133  
13 2     2   17 use Fcntl "S_IRUSR";
  2         5  
  2         88  
14 2     2   1505 use Format::Human::Bytes;
  2         1092  
  2         1587  
15              
16             sub _decorate_dirs {
17 2     2   7 my ($dir, $dirs) = @_;
18 2         5 my @ls_dirs = ();
19 2         3 for my $basename (@{$dirs}) {
  2         7  
20 1         6 my $subdir = $dir->subdir($basename);
21 1         79 my @subdirs = (); # the subdirs of this subdir
22 1         2 my $file_count = 0; # the number of files in this subdir
23 1         6 while (my $ent = $subdir->next) {
24 5         1262 my $subsubname = $ent->basename;
25 5 100       49 next if $subsubname =~ /^\./; # hidden
26 3 50       11 next if $subsubname =~ /~$/; # ignore
27 3 50       12 next unless -r $ent; # can read
28 3 50       228 if ($ent->is_dir) {
29 0         0 push @subdirs, $subsubname;
30             } else {
31 3         32 $file_count++;
32             }
33             }
34 1         64 @subdirs = sort {$a cmp $b} @subdirs;
  0         0  
35 1         12 push @ls_dirs, {
36             name => $basename,
37             subdirs => \@subdirs,
38             file_count => $file_count,
39             };
40             }
41 2         7 return \@ls_dirs;
42             }
43              
44             sub _ymd {
45 3     3   277 my $stamp = shift;
46 3         82 my ($mday, $mon, $year) = (localtime($stamp))[3..5];
47 3         17 my $date = sprintf("%4d-%02d-%02d", $year + 1900, $mon + 1, $mday);
48 3         38 return $date;
49             }
50              
51             sub _decorate_files {
52 2     2   5 my ($dir, $files) = @_;
53 2         6 my @ls_files = ();
54 2         21 my $mt = MIME::Types->new;
55 2         23 for my $basename (@{$files}) {
  2         8  
56 3         11 my $st = $dir->file($basename)->stat;
57 3 50       1024 next unless $st;
58 3 50       14 next unless $st->cando(S_IRUSR, 1); # can read
59 3         55 my $type = $mt->mimeTypeOf($basename);
60 3         542 push @ls_files, {
61             name => $basename,
62             type => "$type",
63             size => Format::Human::Bytes::base2($st->size),
64             date => _ymd($st->mtime),
65             };
66             }
67 2         17 return \@ls_files;
68             }
69              
70             register ls => sub {
71 2     2   215043 my ($dsl, @args) = plugin_args(@_);
72 2         21 my $dir = dir(@args);
73 2         234 my $ls_name = $dir->basename;
74 2         11 my @dirs = ();
75 2         5 my @files = ();
76 2         3 my $ls_dirs;
77             my $ls_files;
78            
79 2 50       11 if (-d $dir) {
80 2         119 while (my $ent = $dir->next) {
81 8         1921 my $basename = $ent->basename;
82 8 100       62 next if $basename =~ /^\./; # hidden
83 4 50       118 next if $basename =~ /~$/; # ignore
84 4 100       16 if ($ent->is_dir) {
85 1 50       7 next unless -r $ent; # can read
86 1         45 push @dirs, $basename;
87             } else {
88 3         32 push @files, $basename;
89             }
90             }
91 2         206 @dirs = sort {$a cmp $b} @dirs;
  0         0  
92 2         9 $ls_dirs = _decorate_dirs($dir, \@dirs);
93 2         6 @files = sort {$a cmp $b} @files;
  3         8  
94 2         37 $ls_files = _decorate_files($dir, \@files);
95             } else {
96 0         0 push @files, $dir->basename;
97 0         0 $ls_files = _decorate_files($dir->parent, \@files);
98             }
99              
100 2         29 my $ls_cdup = $dsl->request->path;
101 2         35 $ls_cdup =~ s{/[^/]*$}{};
102              
103 2         16 $dsl->var( ls_name => $ls_name );
104 2         43 $dsl->var( ls_cdup => $ls_cdup );
105 2         23 $dsl->var( ls_dirs => $ls_dirs );
106 2         22 $dsl->var( ls_files => $ls_files );
107            
108 2         24 return $dir;
109              
110             };
111              
112             register_plugin;
113             1;
114             __END__