1 package Plack::App::BookReader;
2 use parent qw(Plack::App::File);
11 use Data::Dump qw(dump);
13 # Stolen from rack/directory.rb
14 my $dir_file = "<tr><td class='name'><a href='%s'>%s</a></td><td class='size'>%s</td><td class='type'>%s</td><td class='mtime'>%s</td></tr>";
15 my $dir_page = <<PAGE;
18 <meta http-equiv="content-type" content="text/html; charset=utf-8" />
19 <style type='text/css'>
20 table { width:100%%; }
21 .name { text-align:left; }
22 .size, .mtime { text-align:right; }
24 .mtime { width:15em; }
31 <th class='name'>Name</th>
32 <th class='size'>Size</th>
33 <th class='type'>Type</th>
34 <th class='mtime'>Last Modified</th>
44 my($self, $file) = @_;
45 return -d $file || -f $file;
48 sub return_dir_redirect {
49 my ($self, $env) = @_;
50 my $uri = Plack::Request->new($env)->uri;
53 'Location' => $uri . '/',
54 'Content-Type' => 'text/plain',
55 'Content-Length' => 8,
62 my($self, $env, $dir, $fullpath) = @_;
68 return $self->SUPER::serve_path($env, $dir, $fullpath);
71 my $dir_url = $env->{SCRIPT_NAME} . $env->{PATH_INFO};
73 if ($dir_url !~ m{/$}) {
74 return $self->return_dir_redirect($env);
77 my @files = ([ "../", "Parent Directory", '', '', '' ]);
79 my $dh = DirHandle->new($dir);
81 while (defined(my $ent = $dh->read)) {
88 for my $basename (sort { $a cmp $b } @children) {
89 push @page_files, $basename if $basename =~ m/\.jpg$/;
90 my $file = "$dir/$basename";
91 my $url = $dir_url . $basename;
93 my $is_dir = -d $file;
97 $url = join '/', map {uri_escape($_)} split m{/}, $url;
104 my $mime_type = $is_dir ? 'directory' : ( Plack::MIME->mime_type($file) || 'text/plain' );
105 push @files, [ $url, $basename, $stat[7], $mime_type, HTTP::Date::time2str($stat[9]) ];
108 my $path = Plack::Util::encode_html( $env->{PATH_INFO} );
109 my $files = join "\n", map {
111 sprintf $dir_file, map Plack::Util::encode_html($_), @$f;
115 page_urls => [ map { "$dir_url/$_" } sort { $a <=> $b } @page_files ],
117 my $page = sprintf $dir_page, $path, $path, $files, dump( $meta );
119 return [ 200, ['Content-Type' => 'text/html; charset=utf-8'], [ $page ] ];
128 Plack::App::BookReader - Internet Archive Book Reader with directory index
133 use Plack::App::BookReader;
134 my $app = Plack::App::BookReader->new({ root => "/path/to/htdocs" })->to_app;
138 This is a static file server PSGI application with directory index a la Apache's mod_autoindex.
146 Document root directory. Defaults to the current directory.
153 Tatsuhiko Miyagawa (based on L<Plack::App::Directory>