App-htidx

 view release on metacpan or  search on metacpan

lib/App/htidx.pm  view on Meta::CPAN

    }

    my $mkhtml = scalar(grep { /^index\./i } @files) < 1;

    if (-e $index) {
        open(my $fh, $index);

        while (!$fh->eof) {
            if (index($fh->getline, SIGNATURE) >= 0) {
                $mkhtml = 1;
                last;
            }
        }

        $fh->close;
    }

    mkhtml($index, $dir, $toplevel, \@dirs, \@files) if ($mkhtml);

    map { mkindex(File::Spec->catfile($dir, $_)) } @dirs;
}

sub mkhtml {
    my ($index, $dir, $toplevel, $dref, $fref) = @_;

    my $tmpfile = File::Temp::tempnam($dir, '.mkindex');

    open(my $fh, '>', $index) || die("$index: $!");

    my $title = sprintf('Directory listing of %s/', basename($dir));

    $fh->say('<!doctype html>');
    $fh->say(sprintf('<!-- %s -->', he(SIGNATURE)));
    $fh->say($H->open('html', {lang => 'en'}));

    $fh->say($H->head([
    $H->meta({charset => 'UTF-8'}),
        $H->title(he($title)),
        $H->meta({name => 'generator', content => sprintf('%s v%s', __PACKAGE__, $VERSION)}),
        $H->meta({name => 'viewport', content => 'width=device-width'}),
        $H->style(he($CSS)),
    ]));

    $fh->say($H->open('body', { class => 'htidx-body' }));

    $fh->say($H->h1($title));

    $fh->say($H->open('table'));

    $fh->say($H->thead($H->tr([map { $H->th($_) } ('Name', 'Last Modified', 'Size') ])));

    $fh->say($H->open('tbody'));

    $fh->say($H->tr(
        { class => 'htidx-directory' },
        [
            $H->td($H->a(
                { href => '../'},
                'Parent Directory'
            )),
            $H->td(strftime(TIMEFMT, localtime(stat(File::Spec->catfile(dirname($dir)))->mtime))),
            $H->td('-')
        ]
    )) unless ($toplevel);

    foreach my $entry (@{$dref}) {
        $fh->say($H->tr(
            { class => 'htidx-directory' },
            [ map { $H->td($_) } (
                $H->a(
                    { href => uri_escape($entry).'/'},
                    he($entry.'/')
                ),
                strftime(TIMEFMT, localtime(stat(File::Spec->catfile($dir, $entry))->mtime)),
                '-',
            ) ]
        ));
    }

    foreach my $entry (@{$fref}) {
        my $stat = stat(File::Spec->catfile($dir, $entry));

        $fh->say($H->tr(
            { class => 'htidx-file' },
            [ map { $H->td($_) } (
                $H->a(
                    { href => uri_escape($entry) },
                    he($entry)
                ),
                strftime(TIMEFMT, localtime($stat->mtime)),
                fsize($stat->size),
            ) ]
        ));
    }

    map { $fh->say($H->close($_)) } qw(tbody table body html);

    $fh->close;

    rename($tmpfile, $index);
}

sub fsize {
    my $size = shift;
    if ($size < 1000) {
        return '1K';

    } elsif ($size < 1000 * 1000) {
        return sprintf('%uK', ceil($size / 1000));

    } elsif ($size < 1000 * 1000 * 1000) {
        return sprintf('%uM', ceil($size / (1000 * 1000)));
 
    } else {
        return sprintf('%uG', ceil($size / (1000 * 1000 * 1000)));

    }
}

sub he { $H->entity_encode(@_) }

1;

=pod

=encoding UTF-8

=head1 NAME

App::htidx - generate static HTML directory listings.

=head1 VERSION

version 0.02

=head1 SYNOPSIS

Run C<htidx> on the command line:

    htidx DIRECTORY



( run in 1.748 second using v1.01-cache-2.11-cpan-8f98c5d2c55 )