Plack-Middleware-DirListing

 view release on metacpan or  search on metacpan

lib/Plack/Middleware/DirListing.pm  view on Meta::CPAN

  </tr>
FILE
}

sub last_modified {
  my ($self, $date) = @_;

  return Time::Piece->new( $date )->strftime( "%d-%b-%Y %H:%M" );
 }

sub sort_order {
  my ($self, $env, $page) = @_;

  if (my ($field, $order) = $env->{ QUERY_STRING } =~ /C=(\w);O=(\w)/) {
    my $invert = ($order eq 'A') ? 'D' : 'A';
    $page =~ s/C=$field;O=$order/C=$field;O=$invert/;
   }

  return $page;
 }

my %col_sort = (
	'NA' => sub { $a->[2] cmp $b->[2] },
	'ND' => sub { $b->[2] cmp $a->[2] },
	'MA' => sub { $a->[6] <=> $b->[6] },
	'MD' => sub { $b->[6] <=> $a->[6] },
	'SA' => sub { $a->[4] <=> $b->[4] },
	'SD' => sub { $b->[4] <=> $a->[4] },
	'DA' => sub { $a->[5] cmp $b->[5] },
	'DD' => sub { $b->[5] cmp $a->[5] },
);

sub filetype_class {
  my ($self, $filetype) = @_;

  return 'ft_directory' if ($filetype eq 'directory');
  return 'ft_image' if ($filetype =~ /^image/);
  return 'ft_pdf' if ($filetype =~ /pdf$/);
  return 'ft_html' if ($filetype =~ /html$/);

  return '';
}


sub read_dir {
  my ($self, $env, $dir) = @_;

  my @files;

  my $dh = DirHandle->new($dir);

  while (defined(my $ent = $dh->read)) {
    next if $ent eq '.' or $ent eq '..';

    my $file = "$dir/$ent";
    my $url = $env->{PATH_INFO} . $ent;

    my $is_dir = -d $file;
    my @stat = stat _;

    $url = join '/', map {uri_escape($_)} split m{/}, $url;

    if ($is_dir) {
      $ent .= "/";
      $url .= "/";
    }

    my $mime_type = $is_dir ? 'directory' : ( Plack::MIME->mime_type($file) || 'text/plain' );
    my $filetype_class = $self->filetype_class( $mime_type );
    push @files, [ $filetype_class, $url, $ent, $self->last_modified( $stat[9] ), $stat[7], $mime_type, $stat[9] ];
  }

  my ($field, $order) = $env->{ QUERY_STRING } =~ /C=(\w);O=(\w)/;
  $field ||= 'N';
  $order ||= 'A';

  @files = sort { &{ $col_sort{ "$field$order" } } } @files;

  return [ [ 'ft_parent', "../", "Parent Directory", '', '', '', 0], @files ];
}

sub prepare_app {
    my ($self) = @_;

    $self->root('.')               unless $self->root;
}

# NOTE: Copied from Plack::App::Directory as that module makes it
# impossible to override the HTML.

sub serve_path {
  my $self = shift;
  my ($env, $dir) = @_;

  my $files = $self->read_dir( $env, $dir );

  my $path  = Plack::Util::encode_html("Index of $env->{PATH_INFO}");
  my $files_html = join "\n", map {
    my $f = $_;
    sprintf $self->file_html, map Plack::Util::encode_html($_), @{ $f }[ 0..5 ];
  } @{ $files };
  my $page  = sprintf $self->dir_html, $path, $path, $files_html, $env->{ HTTP_HOST };

  $page = $self->sort_order( $env, $page );

  return [ 200, ['Content-Type' => 'text/html; charset=utf-8'], [ $page ] ];
}

sub call {
    my ( $self, $env ) = @_;
    my $req = Plack::Request->new( $env );

    my $dir = $self->root . $req->path_info();
    if (-d $dir) {
        if (substr( $dir, -1 ) eq '/') {
          return $self->serve_path( $env, $dir );
         }
        else {
          my $uri = $req->uri();
          $uri->path( $uri->path . '/' );
          my $res = $req->new_response(301); # new Plack::Response



( run in 0.550 second using v1.01-cache-2.11-cpan-71847e10f99 )