File Coverage

blib/lib/Dancer/Plugin/Dropbox/AutoIndex.pm
Criterion Covered Total %
statement 54 57 94.7
branch 6 8 75.0
condition 2 4 50.0
subroutine 11 11 100.0
pod 1 1 100.0
total 74 81 91.3


line stmt bran cond sub pod time code
1             package Dancer::Plugin::Dropbox::AutoIndex;
2              
3 3     3   17 use strict;
  3         6  
  3         97  
4 3     3   16 use warnings;
  3         7  
  3         76  
5              
6 3     3   15 use Exporter;
  3         6  
  3         279  
7              
8             our @ISA = qw/Exporter/;
9             our @EXPORT_OK = qw/autoindex/;
10             our $VERSION = '0.01';
11              
12 3     3   19 use File::stat;
  3         5  
  3         29  
13 3     3   23957 use DateTime;
  3         618386  
  3         127  
14 3     3   3095 use Format::Human::Bytes;
  3         1926  
  3         106  
15 3     3   23 use File::Spec;
  3         7  
  3         88  
16 3     3   21 use URI::Escape;
  3         7  
  3         271  
17 3     3   98 use Dancer ":syntax";
  3         6  
  3         28  
18 3     3   1701 use Encode;
  3         7  
  3         1801  
19              
20             =head2 autoindex ($directory, sort_field => "name", fs_encoding => "utf-8")
21              
22             The autoindex function takes as argument a directory and an optional
23             named sort_field parameter for sorting, and returns a arrayref with
24             hashrefs with the relevant file information:
25              
26             [
27             {
28             'location' => './../',
29             'mod_time' => '08-Apr-2013 12:58',
30             'name' => '..',
31             'size' => '-'
32             },
33             {
34             'location' => 'test.txt',
35             'mod_time' => '08-Apr-2013 15:04',
36             'name' => 'test.txt',
37             'size' => '13B'
38             }
39             ];
40              
41             You may want to specify a C parameter to sort the listing
42             (by default "name") and a file system encoding (by default "utf-8");
43              
44              
45             =cut
46              
47             sub autoindex {
48 7     7 1 23 my ($directory, %params) = @_;
49 7         16 my ($name, @files, $st);
50 7 50       113 return [] unless -d $directory;
51 7   50     48 $params{sort_field} ||= 'name';
52 7   50     43 $params{fs_encoding} ||= 'utf-8';
53            
54 7         389 opendir(AUTO, $directory);
55 7         180 while ($name = readdir(AUTO)) {
56              
57             # we have to decode the raw bytes pulled out from readdir, so
58             # let's use a parameter.
59 21         81 $name = decode ($params{fs_encoding}, $name);
60              
61 21         817 my (%file_info, $file_st, $epoch);
62              
63 21 100       187 next if $name eq '.';
64            
65             # more information about the file in question
66 14 50       193 if ($file_st = stat(File::Spec->catfile($directory, $name))) {
67 14         2907 $epoch = $file_st->mtime();
68 14         368 $file_info{mod_time} = DateTime->from_epoch(epoch => $file_st->mtime)->strftime('%d-%b-%Y %H:%M');
69             }
70             else {
71 0         0 $file_info{error} = "$directory, $name, $!";
72 0         0 Dancer::Logger::warning $file_info{error};
73 0         0 next;
74             }
75              
76             # encode it back and escape
77 14         5685 $name = uri_escape_utf8($name);
78 14         282 $file_info{name} = $name;
79              
80 14 100       59 if (-d $file_st) {
81 7         103 $file_info{location} = "./$name/";
82 7         13 $file_info{size} = '-';
83             }
84             else {
85 7         120 $file_info{location} = $name;
86 7         180 $file_info{size} = Format::Human::Bytes::base2($file_st->size());
87             }
88 14         344 push (@files, \%file_info);
89             }
90              
91 7         41 @files = sort {$a->{$params{sort_field}} cmp $b->{$params{sort_field}}} @files;
  7         38  
92 7         44 return \@files;
93             }
94              
95             1;
96