From: Marius Gavrilescu Date: Sat, 18 Jan 2014 12:20:38 +0000 (+0200) Subject: Make all generators inherit from a common base X-Git-Url: http://git.ieval.ro/?a=commitdiff_plain;h=bb95f538bf263c0294d87cfb90d58c66117b9aab;p=plack-app-gruntmaster.git Make all generators inherit from a common base --- diff --git a/lib/Gruntmaster/Data.pm b/lib/Gruntmaster/Data.pm index 94eb507..3855c08 100644 --- a/lib/Gruntmaster/Data.pm +++ b/lib/Gruntmaster/Data.pm @@ -78,7 +78,7 @@ sub clean_job (_){ HDEL cp . "job.$_[0]", qw/result result_text results daemon/ } -our @EXPORT_OK = do { +our @EXPORT = do { no strict 'refs'; grep { $_ =~ /^[a-zA-Z]/ and exists &$_ } keys %{__PACKAGE__ . '::'}; }; diff --git a/lib/Gruntmaster/Page.pm b/lib/Gruntmaster/Page.pm index d90d57c..c7f92bb 100644 --- a/lib/Gruntmaster/Page.pm +++ b/lib/Gruntmaster/Page.pm @@ -27,8 +27,7 @@ sub declaregen{ my ($generator, $regex) = @_; $generator = "Gruntmaster::Page::$generator"; eval "require $generator"; - my $gensub = $generator->can('generate') or die "No such generator: $generator"; - push @generators, [$regex, $gensub]; + push @generators, [$regex, $generator]; } { @@ -63,7 +62,7 @@ sub _generate{ my ($regex, $generator) = @$gen; next unless $path_noext =~ $regex; for my $lang (@{LANGUAGES()}) { - my $page = $generator->($path, $lang); + my $page = $generator->generate($path, $lang); write_file "$path_noext.$lang.$ext.new", $page; say $typemap "URI: $basename.$lang.$ext\nContent-Language: $lang\nContent-Type: " . CONTENT_TYPES->{$ext} . "\n"; gzip \$page => "$path_noext.$lang.gz.$ext.new", Minimal => 1; diff --git a/lib/Gruntmaster/Page/Account.pm b/lib/Gruntmaster/Page/Account.pm index 20acc6a..be27aff 100644 --- a/lib/Gruntmaster/Page/Account.pm +++ b/lib/Gruntmaster/Page/Account.pm @@ -3,15 +3,12 @@ package Gruntmaster::Page::Account; use 5.014000; use strict; use warnings; -use parent qw/Exporter/; -our @EXPORT_OK = qw/generate/; +use Gruntmaster::Page::Base account => 'Account'; +our @ISA = qw/Gruntmaster::Page::Base/; our $VERSION = '0.001'; -use HTML::Template::Compiled; -use Gruntmaster::Page::Common qw/cook_templates reload_templates/; - -my %orig_templates = ( - en => <<'HTML', +use constant TEMPLATES => { + en => <<'HTML',

Register

@@ -44,13 +41,6 @@ Confirm new password:
HTML -); - -my %templates = cook_templates %orig_templates, account => 'Account'; - -sub generate{ - %templates = cook_templates %orig_templates, account => 'Account' if reload_templates; - HTML::Template::Compiled->new(scalarref => \$templates{$_[1]})->output -} +}; 1 diff --git a/lib/Gruntmaster/Page/Base.pm b/lib/Gruntmaster/Page/Base.pm new file mode 100644 index 0000000..7fa1497 --- /dev/null +++ b/lib/Gruntmaster/Page/Base.pm @@ -0,0 +1,115 @@ +package Gruntmaster::Page::Base; + +use 5.014000; +use strict; +use warnings; + +use File::Slurp qw/read_file/; +use HTML::Template::Compiled; + +################################################## + +use POSIX (); +use Gruntmaster::Data (); +use List::Util (); + +sub import { + my $caller = caller; + my ($self, $name, $title) = @_; + + Gruntmaster::Data->export_to_level(1, $caller); + List::Util->export_to_level(1, $caller, qw/sum/); + + no strict 'refs'; + *{"${caller}::strftime"} = \&POSIX::strftime; + *{"${caller}::NAME"} = sub () { $name }; + *{"${caller}::TITLE"} = sub () { $title }; +} + +################################################## + +my %orig_header_templates = ( + en => <<'HTML', + +TITLE_GOES_HERE + + + + + + + +
iEval
+
TITLE_GOES_HERE
+ + + +HTML +); + +my %orig_footer_templates = ( + en => <<'HTML', + + +HTML +); + +sub patch_templates { + my $root = $ENV{GRUNTMASTER_TEMPLATE_ROOT} or return; + my ($templates, $name) = @_; + my %out = %$templates; + for (<$root/$name*>) { + m/\.(.+)$/; + $out{$1} = read_file $_ + } + + %out +} + +sub reload_templates (){ $ENV{GRUNTMASTER_RELOAD_TEMPLATES} } + +my %header_templates = patch_templates \%orig_header_templates, 'header'; +my %footer_templates = patch_templates \%orig_footer_templates, 'footer'; + +sub header{ + my ($language, $title) = @_; + %header_templates = patch_templates \%orig_header_templates, 'header' if reload_templates; + $header_templates{$language} =~ s/TITLE_GOES_HERE/$title/ger; +} + +sub footer{ + %footer_templates = patch_templates \%orig_footer_templates, 'footer' if reload_templates; + $footer_templates{$_[0]}; +} + +sub cook_templates { + my ($templates, $name, $title) = @_; + + my %out = patch_templates $templates, $name; + $out{$_} = header ($_, $title) . $out{$_} for keys %out; + $out{$_} .= footer $_ for keys %out; + + %out +} + +################################################## + +my %templates; + +sub generate{ + my ($self, $path, $lang) = @_; + + $templates{$self} = { cook_templates $self->TEMPLATES, $self->NAME => $self->TITLE } if !exists $templates{$self} or reload_templates; + + my $htc = HTML::Template::Compiled->new(scalarref => \$templates{$self}{$lang}, default_escape => 'HTML',); + $self->_generate($htc, $path, $lang); + $htc->output +} + +sub _generate {} + +1 diff --git a/lib/Gruntmaster/Page/Common.pm b/lib/Gruntmaster/Page/Common.pm deleted file mode 100644 index 37cdf71..0000000 --- a/lib/Gruntmaster/Page/Common.pm +++ /dev/null @@ -1,79 +0,0 @@ -package Gruntmaster::Page::Common; - -use 5.014000; -use strict; -use warnings; -use parent qw/Exporter/; -our @EXPORT_OK = qw/header footer cook_templates reload_templates/; - -use File::Slurp qw/read_file/; - -my %orig_header_templates = ( - en => <<'HTML', - -TITLE_GOES_HERE - - - - - - - -
iEval
-
TITLE_GOES_HERE
- - - -HTML -); - -my %orig_footer_templates = ( - en => <<'HTML', - - -HTML -); - -sub patch_templates { - my $root = $ENV{GRUNTMASTER_TEMPLATE_ROOT} or return; - my ($templates, $name) = @_; - my %out = %$templates; - for (<$root/$name*>) { - m/\.(.+)$/; - $out{$1} = read_file $_ - } - - %out -} - -my %header_templates = patch_templates \%orig_header_templates, 'header'; -my %footer_templates = patch_templates \%orig_footer_templates, 'footer'; - -sub reload_templates () { $ENV{GRUNTMASTER_RELOAD_TEMPLATES} } - -sub header{ - my ($language, $title) = @_; - %header_templates = patch_templates \%orig_header_templates, 'header' if reload_templates; - $header_templates{$language} =~ s/TITLE_GOES_HERE/$title/ger; -} - -sub footer{ - %footer_templates = patch_templates \%orig_footer_templates, 'footer' if reload_templates; - $footer_templates{$_[0]}; -} - -sub cook_templates (\%@) { - my ($templates, $name, $title) = @_; - - my %out = patch_templates $templates, $name; - $out{$_} = header ($_, $title) . $out{$_} for keys %out; - $out{$_} .= footer $_ for keys %out; - - %out -} - -1; diff --git a/lib/Gruntmaster/Page/Ct.pm b/lib/Gruntmaster/Page/Ct.pm index 1c108fd..f5c6c1f 100644 --- a/lib/Gruntmaster/Page/Ct.pm +++ b/lib/Gruntmaster/Page/Ct.pm @@ -3,16 +3,11 @@ package Gruntmaster::Page::Ct; use 5.014000; use strict; use warnings; -use parent qw/Exporter/; -our @EXPORT_OK = qw/generate/; +use Gruntmaster::Page::Base ct => 'Contests'; +our @ISA = qw/Gruntmaster::Page::Base/; our $VERSION = '0.001'; -use HTML::Template::Compiled; -use POSIX qw/strftime/; -use Gruntmaster::Page::Common qw/cook_templates reload_templates/; -use Gruntmaster::Data qw/contests contest_name contest_start contest_end contest_owner/; - -my %orig_templates = ( +use constant TEMPLATES => { en => <<'HTML',

Running contests

@@ -56,13 +51,10 @@ my %orig_templates = (
HTML -); - -my %templates = cook_templates %orig_templates, ct => 'Contests'; +}; -sub generate{ - %templates = cook_templates %orig_templates, ct => 'Contests' if reload_templates; - my $htc = HTML::Template::Compiled->new(scalarref => \$templates{$_[1]}); +sub _generate{ + my ($self, $htc, $path, $lang) = @_; my (@running, @pending, @finished); for (contests) { @@ -81,7 +73,6 @@ sub generate{ $htc->param(running => \@running); $htc->param(pending => \@pending); $htc->param(finished => \@finished); - $htc->output } 1 diff --git a/lib/Gruntmaster/Page/Ct/Entry.pm b/lib/Gruntmaster/Page/Ct/Entry.pm index bba2991..6266661 100644 --- a/lib/Gruntmaster/Page/Ct/Entry.pm +++ b/lib/Gruntmaster/Page/Ct/Entry.pm @@ -3,16 +3,11 @@ package Gruntmaster::Page::Ct::Entry; use 5.014000; use strict; use warnings; -use parent qw/Exporter/; -our @EXPORT_OK = qw/generate/; +use Gruntmaster::Page::Base ct_entry => ''; +our @ISA = qw/Gruntmaster::Page::Base/; our $VERSION = '0.001'; -use HTML::Template::Compiled; -use POSIX qw/strftime/; -use Gruntmaster::Page::Common qw/cook_templates reload_templates/; -use Gruntmaster::Data qw/contest_name contest_start contest_end/; - -my %orig_templates = ( +use constant TEMPLATES => { en => <<'HTML', Contest start time:
Contest end time:

@@ -21,23 +16,18 @@ Contest end time:

Job log
Standings HTML -); +}; -my %templates = cook_templates %orig_templates, ct_entry => ''; +sub _generate{ + my ($self, $htc, $path, $lang) = @_; -sub generate{ - %templates = cook_templates %orig_templates, ct_entry => '' if reload_templates; - my ($path, $lang) = @_; $path = ($path =~ m,ct/(.*)/index,)[0]; - my $template = $templates{$lang}; - my $htc = HTML::Template::Compiled->new(scalarref => \$template); $htc->param(id => $path); $htc->param(name => contest_name $path); $htc->param(start => strftime '%c', contest_start); $htc->param(end => strftime '%c', contest_end); $htc->param(started => time >= contest_start); - $htc->output } 1 diff --git a/lib/Gruntmaster/Page/Index.pm b/lib/Gruntmaster/Page/Index.pm index 0214ea6..a413e6a 100644 --- a/lib/Gruntmaster/Page/Index.pm +++ b/lib/Gruntmaster/Page/Index.pm @@ -3,23 +3,13 @@ package Gruntmaster::Page::Index; use 5.014000; use strict; use warnings; -use parent qw/Exporter/; -our @EXPORT_OK = qw/generate/; +use Gruntmaster::Page::Base index => 'Gruntmaster 6000'; +our @ISA = qw/Gruntmaster::Page::Base/; our $VERSION = '0.001'; -use HTML::Template::Compiled; -use Gruntmaster::Page::Common qw/cook_templates reload_templates/; - -my %orig_templates = ( - en => <<'HTML', +use constant TEMPLATES => { + en => <<'HTML', HTML -); - -my %templates = cook_templates %orig_templates, index => 'Gruntmaster 6000'; - -sub generate{ - %templates = cook_templates %orig_templates, index => 'Gruntmaster 6000' if reload_templates; - HTML::Template::Compiled->new(scalarref => \$templates{$_[1]})->output -} +}; 1 diff --git a/lib/Gruntmaster/Page/Learn.pm b/lib/Gruntmaster/Page/Learn.pm index 171a184..95c6182 100644 --- a/lib/Gruntmaster/Page/Learn.pm +++ b/lib/Gruntmaster/Page/Learn.pm @@ -3,25 +3,15 @@ package Gruntmaster::Page::Learn; use 5.014000; use strict; use warnings; -use parent qw/Exporter/; -our @EXPORT_OK = qw/generate/; +use Gruntmaster::Page::Base learn => 'Learn'; +our @ISA = qw/Gruntmaster::Page::Base/; our $VERSION = '0.001'; -use HTML::Template::Compiled; -use Gruntmaster::Page::Common qw/cook_templates reload_templates/; - -my %orig_templates = ( - en => <<'HTML', +use constant TEMPLATES => { + en => <<'HTML', Install interactive-perl-tutorial from your nearest CPAN mirror. Run cpan App::InteractivePerlTutorial.

You can also get the source from git.ieval.ro HTML -); - -my %templates = cook_templates %orig_templates, learn => 'Learn'; - -sub generate{ - %templates = cook_templates %orig_templates, learn => 'Learn' if reload_templates; - HTML::Template::Compiled->new(scalarref => \$templates{$_[1]})->output; -} +}; 1 diff --git a/lib/Gruntmaster/Page/Log.pm b/lib/Gruntmaster/Page/Log.pm index 47c8a2e..fce36cb 100644 --- a/lib/Gruntmaster/Page/Log.pm +++ b/lib/Gruntmaster/Page/Log.pm @@ -3,8 +3,8 @@ package Gruntmaster::Page::Log; use 5.014000; use strict; use warnings; -use parent qw/Exporter/; -our @EXPORT_OK = qw/generate/; +use Gruntmaster::Page::Base log => 'Job log'; +our @ISA = qw/Gruntmaster::Page::Base/; our $VERSION = '0.001'; use constant PAGE_SIZE => 10; @@ -13,12 +13,7 @@ use constant FORMAT_EXTENSION => { CPP => 'cpp', }; -use HTML::Template::Compiled; -use POSIX qw/strftime/; -use Gruntmaster::Page::Common qw/cook_templates reload_templates/; -use Gruntmaster::Data qw/jobcard job_date job_extension job_filesize problem_name job_private job_problem job_result job_result_text job_user/; - -my %orig_templates = ( +use constant TEMPLATES => { en => <<'HTML', @@ -32,18 +27,16 @@ my %orig_templates = (
HTML -); +}; -my %templates = cook_templates %orig_templates, log => 'Job log'; +sub _generate{ + my ($self, $htc, $path, $lang) = @_; -sub generate{ - %templates = cook_templates %orig_templates, log => 'Job log' if reload_templates; - $_[0] =~ m,^(?:ct/([^/]+)/)?log/(\w+)\.html$,; + $path =~ m,^(?:ct/([^/]+)/)?log/(\w+)\.html$,; local $Gruntmaster::Data::contest = $1; my $pages = jobcard / PAGE_SIZE; my $page = $2 eq 'index' ? $pages : $2; - my $htc = HTML::Template::Compiled->new(scalarref => \$templates{$_[1]}); my @log = sort { $b->{id} <=> $a->{id} } map +{ id => $_, (job_private() ? (private => job_private) : ()), @@ -56,7 +49,6 @@ sub generate{ size => sprintf ("%.2f KiB", job_filesize() / 1024), user => job_user}, ($page - 1) * PAGE_SIZE + 1 .. $page == $pages ? jobcard : $page * PAGE_SIZE; $htc->param(log => \@log); - $htc->output } 1 diff --git a/lib/Gruntmaster/Page/Log/Entry.pm b/lib/Gruntmaster/Page/Log/Entry.pm index 8fed9a1..e20c891 100644 --- a/lib/Gruntmaster/Page/Log/Entry.pm +++ b/lib/Gruntmaster/Page/Log/Entry.pm @@ -3,16 +3,11 @@ package Gruntmaster::Page::Log::Entry; use 5.014000; use strict; use warnings; -use parent qw/Exporter/; -our @EXPORT_OK = qw/generate/; +use Gruntmaster::Page::Base log_entry => 'Job '; +our @ISA = qw/Gruntmaster::Page::Base/; our $VERSION = '0.001'; -use HTML::Template::Compiled; -use POSIX qw/strftime/; -use Gruntmaster::Page::Common qw/cook_templates reload_templates/; -use Gruntmaster::Data qw/job_results/; - -my %orig_templates = ( +use constant TEMPLATES => { en => <<'HTML', @@ -22,18 +17,15 @@ my %orig_templates = (
HTML -); +}; -my %templates = cook_templates %orig_templates, log_entry => 'Job '; +sub _generate{ + my ($self, $htc, $path, $lang) = @_; -sub generate{ - %templates = cook_templates %orig_templates, log_entry => 'Job ' if reload_templates; - $_[0] =~ m,^(?:ct/([^/]+)/)?log/job/([^/]+)\.html$,; + $path =~ m,^(?:ct/([^/]+)/)?log/job/([^/]+)\.html$,; local $Gruntmaster::Data::contest = $1; my $id = $2; - my $htc = HTML::Template::Compiled->new(scalarref => \$templates{$_[1]}); - my @tests = map { $_->{time} = sprintf "%.4fs", $_->{time}; $_ @@ -41,7 +33,6 @@ sub generate{ $htc->param(id => $id); $htc->param(tests => \@tests); - $htc->output } 1 diff --git a/lib/Gruntmaster/Page/Pb.pm b/lib/Gruntmaster/Page/Pb.pm index 18b47bf..8e4a408 100644 --- a/lib/Gruntmaster/Page/Pb.pm +++ b/lib/Gruntmaster/Page/Pb.pm @@ -3,19 +3,12 @@ package Gruntmaster::Page::Pb; use 5.014000; use strict; use warnings; -use parent qw/Exporter/; -our @EXPORT_OK = qw/generate/; +use Gruntmaster::Page::Base pb => 'Problems'; +our @ISA = qw/Gruntmaster::Page::Base/; our $VERSION = '0.001'; -use Fcntl qw/:flock/; -use HTML::Template::Compiled; -use IO::File; -use POSIX qw/strftime/; -use Gruntmaster::Page::Common qw/cook_templates reload_templates/; -use Gruntmaster::Data qw/problem_name problem_level problems/; - -my %orig_templates = ( - en => <<'HTML', +use constant TEMPLATES => { + en => <<'HTML',

Beginner

    @@ -43,26 +36,24 @@ my %orig_templates = (
HTML -); +}; -my %templates = cook_templates %orig_templates, pb => 'Problems'; +sub _generate{ + my ($self, $htc, $path, $lang) = @_; -sub generate{ - %templates = cook_templates %orig_templates, pb => 'Problems' if reload_templates; - $_[0] =~ m,^(?:ct/([^/]+)/)?pb/index.html$,; + $path =~ m,^(?:ct/([^/]+)/)?pb/index.html$,; local $Gruntmaster::Data::contest = $1; - my $htc = HTML::Template::Compiled->new(scalarref => \$templates{$_[1]}); my @problems = sort { $b->{name} cmp $a->{name} } map +{ id => $_, name => problem_name, level => problem_level}, problems; + for my $d (qw/beginner easy medium advanced hard/) { $htc->param($d => [grep {$_->{level} and $_->{level} eq $d} @problems]); } $htc->param(levels => grep { $_->{level} } @problems); $htc->param(problems => \@problems); - $htc->output } 1 diff --git a/lib/Gruntmaster/Page/Pb/Entry.pm b/lib/Gruntmaster/Page/Pb/Entry.pm index dbfbe18..5232592 100644 --- a/lib/Gruntmaster/Page/Pb/Entry.pm +++ b/lib/Gruntmaster/Page/Pb/Entry.pm @@ -3,18 +3,13 @@ package Gruntmaster::Page::Pb::Entry; use 5.014000; use strict; use warnings; -use parent qw/Exporter/; -our @EXPORT_OK = qw/generate/; +use Gruntmaster::Page::Base pb_entry => ''; +our @ISA = qw/Gruntmaster::Page::Base/; our $VERSION = '0.001'; -use HTML::Template::Compiled; -use POSIX qw/strftime/; -use Gruntmaster::Page::Common qw/cook_templates reload_templates/; -use Gruntmaster::Data qw/contest_start contest_end problem_name problem_statement/; - use constant FORMATS => [qw/CPP/]; -my %orig_templates = ( +use constant TEMPLATES => { en => <<'HTML', @@ -33,16 +28,14 @@ my %orig_templates = ( HTML -); +}; -my %templates = cook_templates %orig_templates, pb_entry => ''; +sub _generate{ + my ($self, $htc, $path, $lang) = @_; -sub generate{ - %templates = cook_templates %orig_templates, pb_entry => '' if reload_templates; - $_[0] =~ m,(?:ct/([^/])+/)?pb/(\w+)\.html$,; + $path =~ m,(?:ct/([^/])+/)?pb/(\w+)\.html$,; my ($contest, $id) = ($1, $2); - my $htc = HTML::Template::Compiled->new(scalarref => \$templates{$_[1]}); $htc->param(cansubmit => 1); if (defined $contest) { @@ -54,7 +47,6 @@ sub generate{ local $Gruntmaster::Data::contest = $contest if $contest; $htc->param(name => problem_name $id); $htc->param(statement => problem_statement $id); - $htc->output } 1 diff --git a/lib/Gruntmaster/Page/St.pm b/lib/Gruntmaster/Page/St.pm index e3873ba..dafd5df 100644 --- a/lib/Gruntmaster/Page/St.pm +++ b/lib/Gruntmaster/Page/St.pm @@ -3,17 +3,11 @@ package Gruntmaster::Page::St; use 5.014000; use strict; use warnings; -use parent qw/Exporter/; -our @EXPORT_OK = qw/generate/; +use Gruntmaster::Page::Base st => 'Standings'; +our @ISA = qw/Gruntmaster::Page::Base/; our $VERSION = '0.001'; -use HTML::Template::Compiled; -use List::Util qw/sum/; -use POSIX qw/strftime/; -use Gruntmaster::Page::Common qw/cook_templates reload_templates/; -use Gruntmaster::Data qw/problems jobcard job_result_text job_result job_problem job_user/; - -my %orig_templates = ( +use constant => TEMPLATES => { en => <<'HTML', @@ -25,14 +19,12 @@ my %orig_templates = (
HTML -); +}; -my %templates = cook_templates %orig_templates, st => 'Standings'; +sub _generate{ + my ($self, $htc, $path, $lang) = @_; -sub generate{ - %templates = cook_templates %orig_templates, st => 'Standings' if reload_templates; - local $Gruntmaster::Data::contest = ($_[0] =~ m,^ct/([^/]+)/,)[0]; - my $htc = HTML::Template::Compiled->new(scalarref => \$templates{$_[1]}); + local $Gruntmaster::Data::contest = ($path =~ m,^ct/([^/]+)/,)[0]; my @problems = sort problems; my %scores; @@ -54,7 +46,6 @@ sub generate{ } keys %scores; $htc->param(problems => \@problems); $htc->param(st => \@st); - $htc->output } 1 diff --git a/lib/Gruntmaster/Page/Submit.pm b/lib/Gruntmaster/Page/Submit.pm index 7e4d163..cdb4f7d 100644 --- a/lib/Gruntmaster/Page/Submit.pm +++ b/lib/Gruntmaster/Page/Submit.pm @@ -3,17 +3,13 @@ package Gruntmaster::Page::Submit; use 5.014000; use strict; use warnings; -use parent qw/Exporter/; -our @EXPORT_OK = qw/generate/; +use Gruntmaster::Page::Base submit => 'Submit job'; +our @ISA = qw/Gruntmaster::Page::Base/; our $VERSION = '0.001'; use constant FORMATS => [qw/CPP/]; -use HTML::Template::Compiled; -use Gruntmaster::Page::Common qw/cook_templates reload_templates/; -use Gruntmaster::Data qw/problem_name problems/; - -my %orig_templates = ( +use constant TEMPLATES => { en => <<'HTML',