File Coverage

blib/lib/Dancer2/Plugin/Path/Class.pm
Criterion Covered Total %
statement 10 12 83.3
branch n/a
condition n/a
subroutine 4 4 100.0
pod n/a
total 14 16 87.5


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 1     1   20955 use strict;
  1         2  
  1         27  
6 1     1   5 use warnings;
  1         2  
  1         43  
7              
8             our $VERSION = 0.04;
9              
10 1     1   768 use Dancer2::Plugin;
  1         106907  
  1         7  
11 1     1   581 use MIME::Types;
  0            
  0            
12             use Path::Class;
13             use Fcntl "S_IRUSR";
14             use Format::Human::Bytes;
15              
16             sub _decorate_dirs {
17             my ($dir, $dirs) = @_;
18             my @ls_dirs = ();
19             for my $basename (@{$dirs}) {
20             my $subdir = $dir->subdir($basename);
21             my @subdirs = (); # the subdirs of this subdir
22             my $file_count = 0; # the number of files in this subdir
23             while (my $ent = $subdir->next) {
24             my $subsubname = $ent->basename;
25             next if $subsubname =~ /^\./; # hidden
26             next if $subsubname =~ /~$/; # ignore
27             next unless -r $ent; # can read
28             if ($ent->is_dir) {
29             push @subdirs, $subsubname;
30             } else {
31             $file_count++;
32             }
33             }
34             @subdirs = sort {$a cmp $b} @subdirs;
35             push @ls_dirs, {
36             name => $basename,
37             subdirs => \@subdirs,
38             file_count => $file_count,
39             };
40             }
41             return \@ls_dirs;
42             }
43              
44             sub _ymd {
45             my $stamp = shift;
46             my ($mday, $mon, $year) = (localtime($stamp))[3..5];
47             my $date = sprintf("%4d-%02d-%02d", $year + 1900, $mon + 1, $mday);
48             return $date;
49             }
50              
51             sub _decorate_files {
52             my ($dir, $files) = @_;
53             my @ls_files = ();
54             my $mt = MIME::Types->new;
55             for my $basename (@{$files}) {
56             my $st = $dir->file($basename)->stat;
57             next unless $st;
58             next unless $st->cando(S_IRUSR, 1); # can read
59             my $type = $mt->mimeTypeOf($basename);
60             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             return \@ls_files;
68             }
69              
70             register ls => sub {
71             my ($dsl, @args) = plugin_args(@_);
72             my $dir = dir(@args);
73             my $ls_name = $dir->basename;
74             my @dirs = ();
75             my @files = ();
76             my $ls_dirs;
77             my $ls_files;
78            
79             if (-d $dir) {
80             while (my $ent = $dir->next) {
81             my $basename = $ent->basename;
82             next if $basename =~ /^\./; # hidden
83             next if $basename =~ /~$/; # ignore
84             if ($ent->is_dir) {
85             next unless -r $ent; # can read
86             push @dirs, $basename;
87             } else {
88             push @files, $basename;
89             }
90             }
91             @dirs = sort {$a cmp $b} @dirs;
92             $ls_dirs = _decorate_dirs($dir, \@dirs);
93             @files = sort {$a cmp $b} @files;
94             $ls_files = _decorate_files($dir, \@files);
95             } else {
96             push @files, $dir->basename;
97             $ls_files = _decorate_files($dir->parent, \@files);
98             }
99              
100             my $ls_cdup = $dsl->request->path;
101             $ls_cdup =~ s{/[^/]*$}{};
102              
103             $dsl->var( ls_name => $ls_name );
104             $dsl->var( ls_cdup => $ls_cdup );
105             $dsl->var( ls_dirs => $ls_dirs );
106             $dsl->var( ls_files => $ls_files );
107            
108             return $dir;
109              
110             };
111              
112             register_plugin;
113             1;
114             __END__