34 files changed, 42 insertions(+), 190 deletions(-)
R gemini/site/.static/images/atom.png => gmi/site/.static/images/atom.png
R gemini/site/.static/images/bvbrows.gif => gmi/site/.static/images/bvbrows.gif
R gemini/site/.static/images/favicon.png => gmi/site/.static/images/favicon.png
R gemini/site/.static/images/halp-icon.jpg => gmi/site/.static/images/halp-icon.jpg
R gemini/site/.static/images/mothracompat.gif => gmi/site/.static/images/mothracompat.gif
R gemini/site/.static/images/valid-atom.png => gmi/site/.static/images/valid-atom.png
R gemini/site/.static/images/valid-html5.png => gmi/site/.static/images/valid-html5.png
R gemini/site/.static/images/vcss-blue => gmi/site/.static/images/vcss-blue
R gemini/templates/directory_listing.gmi.tpl => gmi/templates/directory_listing.gmi.tpl
R gemini/templates/menu.gmi.tpl => gmi/templates/menu.gmi.tpl
R gemini/templates/page.gmi.tpl => gmi/templates/page.gmi.tpl
R gemini/templates/sitemap.gmi.tpl => gmi/templates/sitemap.gmi.tpl
M halp.pl
R www/site/.static/images/atom.png => html/site/.static/images/atom.png
R www/site/.static/images/avatar.jpg => html/site/.static/images/avatar.jpg
R www/site/.static/images/bvbrows.gif => html/site/.static/images/bvbrows.gif
R www/site/.static/images/favicon.png => html/site/.static/images/favicon.png
R www/site/.static/images/halp-icon.jpg => html/site/.static/images/halp-icon.jpg
R www/site/.static/images/mothracompat.gif => html/site/.static/images/mothracompat.gif
R www/site/.static/images/valid-atom.png => html/site/.static/images/valid-atom.png
R www/site/.static/images/valid-html5.png => html/site/.static/images/valid-html5.png
R www/site/.static/images/vcss-blue => html/site/.static/images/vcss-blue
R www/site/.static/styles/halp.css => html/site/.static/styles/halp.css
R www/templates/directory_listing.html.tpl => html/templates/directory_listing.html.tpl
R www/templates/menu.html.tpl => html/templates/menu.html.tpl
R www/templates/page.html.tpl => html/templates/page.html.tpl
R www/templates/sitemap.html.tpl => html/templates/sitemap.html.tpl
D lib/Halp/GeminiGenerator.pm
R lib/Halp/{WebGenerator.pm => Generator.pm}
M t/Halp/generation_test.t
A t/expected/gemini/.gitkeep
A t/expected/www/.gitkeep
A tmp/gemini/.gitkeep
A tmp/www/.gitkeep
R gemini/site/.static/images/atom.png => gmi/site/.static/images/atom.png +0 -0
R gemini/site/.static/images/bvbrows.gif => gmi/site/.static/images/bvbrows.gif +0 -0
R gemini/site/.static/images/favicon.png => gmi/site/.static/images/favicon.png +0 -0
R gemini/site/.static/images/halp-icon.jpg => gmi/site/.static/images/halp-icon.jpg +0 -0
R gemini/site/.static/images/mothracompat.gif => gmi/site/.static/images/mothracompat.gif +0 -0
R gemini/site/.static/images/valid-atom.png => gmi/site/.static/images/valid-atom.png +0 -0
R gemini/site/.static/images/valid-html5.png => gmi/site/.static/images/valid-html5.png +0 -0
R gemini/site/.static/images/vcss-blue => gmi/site/.static/images/vcss-blue +0 -0
R gemini/templates/directory_listing.gmi.tpl => gmi/templates/directory_listing.gmi.tpl +0 -0
R => +0 -0
R gemini/templates/page.gmi.tpl => gmi/templates/page.gmi.tpl +0 -0
R gemini/templates/sitemap.gmi.tpl => gmi/templates/sitemap.gmi.tpl +0 -0
M halp.pl => halp.pl +9 -7
@@ 5,8 5,7 @@ use strict;
use warnings;
use Getopt::Long;
-use Halp::GeminiGenerator;
-use Halp::WebGenerator;
+use Halp::Generator;
my %halp_config;
my $config_filename = '';
@@ 31,24 30,27 @@ my $config_hash = do($config_filename);
%halp_config = %$config_hash;
if ($web) {
- my $web_server = Halp::WebGenerator->new(
+ my $web_server = Halp::Generator->new(
author => $halp_config{author},
domain => $halp_config{domain},
host => $halp_config{web}{host},
+ include_stylesheets => 1,
input_path => $halp_config{web}{input_path},
- output_path => $halp_config{web}{output_path}
+ output_path => $halp_config{web}{output_path},
+ template_type => 'html'
);
$web_server->generate();
}
if ($gemini) {
- my $gemini_server = Halp::GeminiGenerator->new(
+ my $gemini_server = Halp::Generator->new(
author => $halp_config{author},
domain => $halp_config{domain},
host => $halp_config{gemini}{host},
+ include_stylesheets => 0,
input_path => $halp_config{gemini}{input_path},
- output_path => $halp_config{gemini}{output_path}
+ output_path => $halp_config{gemini}{output_path},
+ template_type => 'gmi'
);
-
$gemini_server->generate();
}
R www/site/.static/images/atom.png => html/site/.static/images/atom.png +0 -0
R www/site/.static/images/avatar.jpg => html/site/.static/images/avatar.jpg +0 -0
R www/site/.static/images/bvbrows.gif => html/site/.static/images/bvbrows.gif +0 -0
R www/site/.static/images/favicon.png => html/site/.static/images/favicon.png +0 -0
R www/site/.static/images/halp-icon.jpg => html/site/.static/images/halp-icon.jpg +0 -0
R www/site/.static/images/mothracompat.gif => html/site/.static/images/mothracompat.gif +0 -0
R www/site/.static/images/valid-atom.png => html/site/.static/images/valid-atom.png +0 -0
R www/site/.static/images/valid-html5.png => html/site/.static/images/valid-html5.png +0 -0
R www/site/.static/images/vcss-blue => html/site/.static/images/vcss-blue +0 -0
R www/site/.static/styles/halp.css => html/site/.static/styles/halp.css +0 -0
R www/templates/directory_listing.html.tpl => html/templates/directory_listing.html.tpl +0 -0
R => +0 -0
R www/templates/page.html.tpl => html/templates/page.html.tpl +0 -0
R www/templates/sitemap.html.tpl => html/templates/sitemap.html.tpl +0 -0
D lib/Halp/GeminiGenerator.pm => lib/Halp/GeminiGenerator.pm +0 -163
@@ 1,163 0,0 @@
-package Halp::GeminiGenerator;
-
-use strict;
-use warnings;
-
-use Cwd;
-use Data::Dump qw(dump);
-use File::Basename;
-use File::Copy::Recursive "dircopy";
-use File::Slurp;
-use File::Spec qw(abs2rel rel2abs);
-use Halp::AtomFeed;
-use Halp::ContentUtils;
-
-sub new {
- my ($class, %args) = @_;
- my $self = {};
-
- if (!File::Spec->file_name_is_absolute($args{input_path})) {
- $args{input_path} = File::Spec->rel2abs($args{input_path}, cwd());
- }
-
- if (!File::Spec->file_name_is_absolute($args{output_path})) {
- $args{output_path} = File::Spec->rel2abs($args{output_path}, cwd());
- }
-
- $self->{author} = $args{author};
- $self->{domain} = $args{domain};
- $self->{host} = $args{host};
- $self->{input_path} = $args{input_path};
- $self->{output_path} = $args{output_path};
-
- $self->{template_path} = File::Spec->catfile(cwd(), "gemini/templates");
- $self->{default_site_path} = File::Spec->catfile(cwd(), "gemini/site");
-
- return bless $self, $class;
-}
-
-sub generate_menu {
- my ($self, $request_path) = @_;
-
- my $template_pathname = File::Spec->catfile($self->{template_path}, 'menu.gmi.tpl');
- my $template = Text::Template->new(SOURCE => $template_pathname);
-
- my @items = ({ href => '/', title => 'Home' });
- my @listing = directory_listing($self->{input_path}, $self->{input_path}, 0);
- push(@items, @listing);
-
- my $result = $template->fill_in(HASH => { 'items' => \@items } );
- return $result;
-}
-
-sub wrap_page_template {
- my ($self, $title, $content, $show_atom_link, $source_filename) = @_;
-
- my $menu = $self->generate_menu($self->{input_path});
- my $template_pathname = File::Spec->catfile($self->{template_path}, 'page.gmi.tpl');
- my $template = Text::Template->new(SOURCE => $template_pathname);
- my $atom_url = File::Spec->catfile(dirname(File::Spec->abs2rel($source_filename, $self->{input_path})), "feed.xml");
-
- my $footer = '';
- my $footer_pathname = '';
- if (-f $source_filename) {
- $footer_pathname = File::Spec->catfile(dirname($source_filename), '.footer.gmi');
- } elsif (-d $source_filename) {
- $footer_pathname = File::Spec->catfile($source_filename, '.footer.gmi');
- }
- if (-f $footer_pathname) {
- $footer = read_file($footer_pathname);
- }
-
- my $atom_feed = '';
- if ($show_atom_link) {
- $atom_feed = "=> $atom_url Atom Feed\n"
- }
-
- my $result = $template->fill_in(HASH => {'title' => $title, 'content' => $content, 'menu' => $menu, 'atom_feed' => $atom_feed, 'footer' => $footer});
-
- return $result;
-}
-
-sub generate_file {
- my ($self, $source_file) = @_;
-
- my $relative_file = File::Spec->abs2rel($source_file, $self->{input_path});
- my $output_file = File::Spec->catfile($self->{output_path}, $relative_file);
-
- my ($extension) = $source_file =~ /\.([^.]*)$/;
- my $content = read_file($source_file, binmode => ':bytes');
-
- if ($extension eq "gmi") {
- $content = $self->wrap_page_template(file_title($source_file), $content, 0, $source_file);
- }
-
- open my $content_file, '>', $output_file or die "Can't open '$output_file'";
- binmode $content_file;
- print $content_file $content;
- close $content_file;
-}
-
-sub generate_directory {
- my ($self, $source_path) = @_;
-
- my $relative_path = File::Spec->abs2rel($source_path, $self->{input_path});
- my $output_path = File::Spec->catfile($self->{output_path}, $relative_path);
-
- if (!-e $output_path) {
- mkdir($output_path) or die "Unable to create directory '$output_path' - $!";
- }
-
- my $title = directory_title($source_path);
-
- my $directory_description = "";
- my $description_pathname = File::Spec->catfile($source_path, '.description.gmi');
- if (-f $description_pathname) {
- $directory_description = read_file($description_pathname);
- $directory_description =~ s/\s+$//;
- }
-
- if ($relative_path !~ /^\..+$/) {
- my $template_pathname = File::Spec->catfile($self->{template_path}, 'directory_listing.gmi.tpl');
- my $template = Text::Template->new(SOURCE => $template_pathname);
- my @items = directory_listing($self->{input_path}, $source_path, 0);
- my $result = $template->fill_in(HASH => {'path' => $source_path,
- 'directory_description' => $directory_description,
- 'items' => \@items});
- $result = $self->wrap_page_template($title, $result, 1, $source_path);
-
- my $index_file = File::Spec->catfile($output_path, "index.gmi");
- open my $file, '>', $index_file or die "Can't open '$index_file'";
- print $file $result;
- close $file;
-
- my $atom_file = File::Spec->catfile($output_path, "feed.xml");
- my $atom_feed = feed_for($self->{host}, $source_path, $self->{input_path}, $self->{domain}, $self->{author});
- open $file, '>', $atom_file or die "Can't open '$index_file'";
- print $file $atom_feed;
- close $file;
- }
-
- my @files = <"$source_path/*" "$source_path/.*">;
- foreach my $filename (@files) {
- my $relative_file = basename($filename);
- if ($relative_file =~ m/^\.+$/) {
- # Ignore . and ..
- } elsif (-f $filename && $relative_file =~ m/^\./) {
- # Ignore dotfiles
- } elsif (-d $filename) {
- $self->generate_directory($filename);
- } elsif (-f $filename) {
- $self->generate_file($filename);
- }
- }
-}
-
-sub generate {
- my ($self) = @_;
-
- dircopy($self->{default_site_path}, $self->{output_path}) or die $!;
- $self->generate_directory($self->{input_path});
-}
-
-1;
R lib/Halp/WebGenerator.pm => lib/Halp/Generator.pm +31 -20
@@ 1,7 1,8 @@
-package Halp::WebGenerator;
+package Halp::Generator;
use strict;
use warnings;
+use feature "switch";
use Cwd;
use Data::Dump qw(dump);
@@ 25,17 26,16 @@ sub new {
$args{output_path} = File::Spec->rel2abs($args{output_path}, cwd());
}
- # die "input_path $args{input_path} must be absolute" unless
- # die "output_path $args{output_path} must be absolute" unless File::Spec->file_name_is_absolute($args{output_path});
-
$self->{author} = $args{author};
$self->{domain} = $args{domain};
$self->{host} = $args{host};
+ $self->{include_stylesheets} = $args{include_stylesheets};
$self->{input_path} = $args{input_path};
$self->{output_path} = $args{output_path};
+ $self->{template_type} = $args{template_type};
- $self->{template_path} = File::Spec->catfile(cwd(), "www/templates");
- $self->{default_site_path} = File::Spec->catfile(cwd(), "www/site");
+ $self->{template_path} = File::Spec->catfile(cwd(), "$self->{template_type}/templates");
+ $self->{default_site_path} = File::Spec->catfile(cwd(), "$self->{template_type}/site");
return bless $self, $class;
}
@@ 43,7 43,7 @@ sub new {
sub generate_menu {
my ($self, $request_path) = @_;
- my $template_pathname = File::Spec->catfile($self->{template_path}, 'menu.html.tpl');
+ my $template_pathname = File::Spec->catfile($self->{template_path}, "menu.$self->{template_type}.tpl");
my $template = Text::Template->new(SOURCE => $template_pathname);
my @items = ({ href => '/', title => 'Home' });
@@ 58,16 58,16 @@ sub wrap_page_template {
my ($self, $title, $content, $show_atom_link, $source_filename) = @_;
my $menu = $self->generate_menu($self->{input_path});
- my $template_pathname = File::Spec->catfile($self->{template_path}, 'page.html.tpl');
+ my $template_pathname = File::Spec->catfile($self->{template_path}, "page.$self->{template_type}.tpl");
my $template = Text::Template->new(SOURCE => $template_pathname);
my $atom_url = File::Spec->catfile(dirname(File::Spec->abs2rel($source_filename, $self->{input_path})), "feed.xml");
my $footer = '';
my $footer_pathname = '';
if (-f $source_filename) {
- $footer_pathname = File::Spec->catfile(dirname($source_filename), '.footer.html');
+ $footer_pathname = File::Spec->catfile(dirname($source_filename), ".footer.$self->{template_type}");
} elsif (-d $source_filename) {
- $footer_pathname = File::Spec->catfile($source_filename, '.footer.html');
+ $footer_pathname = File::Spec->catfile($source_filename, ".footer.$self->{template_type}");
}
if (-f $footer_pathname) {
$footer = read_file($footer_pathname);
@@ 75,15 75,22 @@ sub wrap_page_template {
my $atom_feed = '';
if ($show_atom_link) {
- $atom_feed = "<a href='$atom_url'><img class='feed-logo' src='/.static/images/atom.png' alt='Atom Feed'></a>";
+ my $template_type = $self->{template_type};
+ given ($template_type) {
+ when ('html') { $atom_feed = "<a href='$atom_url'><img class='feed-logo' src='/.static/images/atom.png' alt='Atom Feed'></a>"; }
+ when ('gmi') { $atom_feed = "=> $atom_url Atom Feed\n"; }
+ default { die "Unsupported template type"; }
+ }
}
my @stylesheets = [];
- my $custom_css_pathname = File::Spec->catfile($self->{input_path}, ".static/styles/custom.css");
- if (-f $custom_css_pathname) {
- @stylesheets = ['halp.css', 'custom.css'];
- } else {
- @stylesheets = ['halp.css'];
+ if ($self->{include_stylesheets}) {
+ my $custom_css_pathname = File::Spec->catfile($self->{input_path}, ".static/styles/custom.css");
+ if (-f $custom_css_pathname) {
+ @stylesheets = ['halp.css', 'custom.css'];
+ } else {
+ @stylesheets = ['halp.css'];
+ }
}
my $result = $template->fill_in(HASH => {'title' => $title, 'content' => $content, 'menu' => $menu, 'atom_feed' => $atom_feed, 'stylesheets' => @stylesheets, 'footer' => $footer});
@@ 100,7 107,7 @@ sub generate_file {
my ($extension) = $source_file =~ /\.([^.]*)$/;
my $content = read_file($source_file, binmode => ':bytes');
- if ($extension eq "html") {
+ if ($extension eq "$self->{template_type}") {
$content = $self->wrap_page_template(file_title($source_file), $content, 0, $source_file);
}
@@ 123,14 130,15 @@ sub generate_directory {
my $title = directory_title($source_path);
my $directory_description = "";
- my $description_pathname = File::Spec->catfile($source_path, '.description.html');
+ my $description_pathname = File::Spec->catfile($source_path, ".description.$self->{template_type}");
if (-f $description_pathname) {
$directory_description = read_file($description_pathname);
$directory_description =~ s/\s+$//;
}
if ($relative_path !~ /^\..+$/) {
- my $template_pathname = File::Spec->catfile($self->{template_path}, 'directory_listing.html.tpl');
+ my $template_pathname = File::Spec->catfile($self->{template_path}, "directory_listing.$self->{template_type}.tpl");
+ print "$template_pathname\n";
my $template = Text::Template->new(SOURCE => $template_pathname);
my @items = directory_listing($self->{input_path}, $source_path, 0);
my $result = $template->fill_in(HASH => {'path' => $source_path,
@@ 138,7 146,7 @@ sub generate_directory {
'items' => \@items});
$result = $self->wrap_page_template($title, $result, 1, $source_path);
- my $index_file = File::Spec->catfile($output_path, "index.html");
+ my $index_file = File::Spec->catfile($output_path, "index.$self->{template_type}");
open my $file, '>', $index_file or die "Can't open '$index_file'";
print $file $result;
close $file;
@@ 169,6 177,9 @@ sub generate_directory {
sub generate {
my ($self) = @_;
+ if (!-d $self->{default_site_path}) { die "Can't find default site path $self->{default_site_path}"; }
+ if (!-d $self->{output_path}) { die "Can't find output path $self->{output_path}"; }
+
dircopy($self->{default_site_path}, $self->{output_path}) or die $!;
$self->generate_directory($self->{input_path});
}
M t/Halp/generation_test.t => t/Halp/generation_test.t +2 -0
@@ 10,6 10,8 @@ use Test::More;
use Test::More tests => 4;
+system("git clean -fdx ./tmp");
+
my $result = system("perl ./halp.pl --config-filename ./dev-config/halp-config.pl --web");
ok($result == 0, "halp --web executed");
A t/expected/gemini/.gitkeep => t/expected/gemini/.gitkeep +0 -0
A t/expected/www/.gitkeep => t/expected/www/.gitkeep +0 -0
A tmp/gemini/.gitkeep => tmp/gemini/.gitkeep +0 -0
A tmp/www/.gitkeep => tmp/www/.gitkeep +0 -0