Introduce Gruntmaster::Page::Generic
authorMarius Gavrilescu <marius@ieval.ro>
Thu, 20 Feb 2014 07:10:17 +0000 (09:10 +0200)
committerMarius Gavrilescu <marius@ieval.ro>
Thu, 20 Feb 2014 07:10:17 +0000 (09:10 +0200)
12 files changed:
lib/Gruntmaster/Page/Base.pm
lib/Gruntmaster/Page/Ct.pm [deleted file]
lib/Gruntmaster/Page/Ct/Entry.pm [deleted file]
lib/Gruntmaster/Page/Generic.pm [new file with mode: 0644]
lib/Gruntmaster/Page/Log/Entry.pm [deleted file]
lib/Gruntmaster/Page/Pb.pm [deleted file]
lib/Gruntmaster/Page/Us.pm [deleted file]
lib/Gruntmaster/Page/Us/Entry.pm [deleted file]
lib/Plack/App/Gruntmaster.pm
tmpl/log_entry.en
tmpl/pb.en
tmpl/us.en

index 9e2d03034cc5c8550499301beb3a67d6825199e5..6ced6145a68eff7367d87293f4963258fa861985 100644 (file)
@@ -38,9 +38,10 @@ use LWP::UserAgent;
 my $ua = LWP::UserAgent->new;
 my %templates;
 
-sub import {
-       my $caller = caller;
-       my ($self, $name, $title) = @_;
+use Carp qw/cluck/;
+
+sub import_to {
+       my ($self, $caller, $name, $title) = @_;
 
        Gruntmaster::Data->export_to_level(1, $caller);
        List::Util->export_to_level(1, $caller, qw/sum/);
@@ -65,6 +66,12 @@ sub import {
        }
 }
 
+sub import {
+       return unless $_[0] eq __PACKAGE__;
+       splice @_, 1, 0, scalar caller;
+       goto &import_to
+}
+
 ##################################################
 
 sub generate{
@@ -80,7 +87,7 @@ sub generate{
 
 sub _generate {}
 
-sub vary {}
+sub vary { '' }
 
 sub max_age { 60 }
 
diff --git a/lib/Gruntmaster/Page/Ct.pm b/lib/Gruntmaster/Page/Ct.pm
deleted file mode 100644 (file)
index a21bf77..0000000
+++ /dev/null
@@ -1,33 +0,0 @@
-package Gruntmaster::Page::Ct;
-
-use 5.014000;
-use strict;
-use warnings;
-use Gruntmaster::Page::Base ct => 'Contests';
-our @ISA = qw/Gruntmaster::Page::Base/;
-our $VERSION = '0.001';
-
-sub _generate{
-       my ($self, $htc, $lang, $env) = @_;
-       debug $env => "language is '$lang'";
-
-       my (@running, @pending, @finished);
-       for (sort {contest_start $a <=> contest_start $b}contests) {
-               my $ct = { id => $_,
-                                  name => contest_name,
-                                  start => strftime ('%c', localtime contest_start),
-                                  end => strftime ('%c', localtime contest_end),
-                                  owner => contest_owner };
-
-               my $time = time;
-               push @pending, $ct if time < contest_start;
-               push @running, $ct if time >= contest_start && time < contest_end;
-               push @finished, $ct if time > contest_end;
-       }
-
-       $htc->param(running => \@running) if @running;
-       $htc->param(pending => \@pending) if @pending;
-       $htc->param(finished => \@finished) if @finished;
-}
-
-1
diff --git a/lib/Gruntmaster/Page/Ct/Entry.pm b/lib/Gruntmaster/Page/Ct/Entry.pm
deleted file mode 100644 (file)
index acc076e..0000000
+++ /dev/null
@@ -1,21 +0,0 @@
-package Gruntmaster::Page::Ct::Entry;
-
-use 5.014000;
-use strict;
-use warnings;
-use Gruntmaster::Page::Base ct_entry => '<tmpl_var name>';
-our @ISA = qw/Gruntmaster::Page::Base/;
-our $VERSION = '0.001';
-
-sub _generate{
-       my ($self, $htc, $lang, $env, $id) = @_;
-       debug $env => "language is '$lang' and id is '$id'";
-
-       $htc->param(id => $id);
-       $htc->param(name => contest_name $id);
-       $htc->param(start => strftime '%c', localtime contest_start $id);
-       $htc->param(end => strftime '%c', localtime contest_end $id);
-       $htc->param(started => time >= contest_start $id);
-}
-
-1
diff --git a/lib/Gruntmaster/Page/Generic.pm b/lib/Gruntmaster/Page/Generic.pm
new file mode 100644 (file)
index 0000000..37e7931
--- /dev/null
@@ -0,0 +1,138 @@
+package Gruntmaster::Page::Generic;
+
+use 5.014000;
+use strict;
+use warnings;
+
+use Gruntmaster::Data;
+use Gruntmaster::Page::Base;
+use JSON qw/decode_json/;
+our @ISA = qw/Gruntmaster::Page::Base/;
+our $VERSION = '0.001';
+
+sub hgetall {
+       my $hash = shift;
+       my $cp = $Gruntmaster::Data::contest ? "contest.$Gruntmaster::Data::contest." : '';
+       map { { id => $_, HGETALL "$cp$hash.$_" } } SMEMBERS "$cp$hash"
+}
+
+sub putsym {
+       my ($key, $value) = @_;
+       no strict 'refs';
+       *{"$key"} = $value;
+}
+
+sub makepkg {
+       my ($pkg, $id, $title) = @_;
+       my $fn = $pkg =~ s,::,/,gr;
+       return if $INC{"$fn.pm"};
+       $INC{"$fn.pm"} = 1;
+       Gruntmaster::Page::Base->import_to($pkg, $id, $title);
+       putsym "${pkg}::ISA", ['Gruntmaster::Page::Base'];
+}
+
+sub make_generate {
+       my %thing = @_;
+       sub {
+               my ($self, $htc, $lang, $env, $ct) = @_;
+               undef $ct unless $thing{contest};
+               debug $env => "Contest is $ct";
+               local $Gruntmaster::Data::contest = $ct if $ct;
+               my @thing = hgetall $thing{hash};
+               @thing = map  { $thing{mangle}->(); $_ } @thing if exists $thing{mangle};
+               @thing = grep { $thing{choose}->() } @thing if exists $thing{choose};
+               @thing = sort { $thing{sortby}->() } @thing if exists $thing{sortby};
+               my %params;
+               $thing{group} //= sub { $thing{id} };
+               for (@thing) {
+                       my $group = $thing{group}->();
+                       $params{$group} //= [];
+                       push $params{$group}, $_
+               }
+               $htc->param(%params);
+       }
+}
+
+sub make_entry_generate{
+       my %thing = @_;
+       sub {
+               my ($self, $htc, $lang, $env, $id, $ct) = @_;
+               ($id, $ct) = ($ct, $id) if $thing{contest};
+               local $Gruntmaster::Data::contest = $ct if $ct;
+               debug $env => "Hash is $thing{hash} and id is $id";
+               my %params = HGETALL "$thing{hash}.$id";
+               $thing{mangle}->(local $_ = \%params) if exists $thing{mangle};
+               %params = (%params, $thing{hook}->(local $_ = \%params)) if exists $thing{hook};
+               $htc->param(%params);
+       }
+}
+
+sub create_thing {
+       my %thing = @_;
+       my $ucid = ucfirst $thing{id};
+       my $pkg = "Gruntmaster::Page::$ucid";
+
+       putsym "${pkg}::_generate", make_generate %thing if makepkg $pkg, @thing{qw/id title/};
+       putsym "${pkg}::Entry::_generate", make_entry_generate %thing if makepkg "${pkg}::Entry", "$thing{id}_entry", '<tmpl_var name>';
+}
+
+sub params;
+sub contest;
+sub choose (&);
+sub sortby (&);
+sub group  (&);
+sub mangle (&);
+sub hook   (&);
+
+sub thing (&){
+       my %thing;
+       no strict 'refs';
+       local *{"params"} = sub { @thing{qw/id hash title/} = @_ };
+       local *{"choose"} = sub { $thing{choose} = shift };
+       local *{"sortby"} = sub { $thing{sortby} = shift };
+       local *{"mangle"} = sub { $thing{mangle} = shift };
+       local *{"group"} = sub { $thing{group} = shift };
+       local *{"contest"} = sub { $thing{contest} = 1 };
+       local *{"hook"} = sub { $thing{hook} = shift };
+       use strict 'refs';
+
+       shift->();
+       create_thing %thing
+}
+
+##################################################
+
+thing {
+       params qw/us user Users/;
+       choose { $_->{name} =~ /\w/ };
+       sortby { lc $a->{name} cmp lc $b->{name} };
+};
+
+thing {
+       params qw/pb problem Problems/;
+       contest;
+       sortby { $a->{name} cmp $b->{name} };
+       group { $_->{level} };
+};
+
+thing {
+       params qw/ct contest Contests/;
+       mangle {
+               $_->{start} = strftime '%c', localtime $_->{start};
+               $_->{end} = strftime '%c', localtime $_->{end};
+       };
+       sortby { $a->{start} <=> $b->{start} };
+       group { time < $_->{start} ? 'pending' : time > $_->{end} ? 'finished' : 'running' };
+       hook { started => time >= $_->{start} };
+};
+
+thing {
+       params qw/log job/, 'Job log';
+       contest;
+       mangle {
+               $_->{results} &&= decode_json $_->{results};
+               $_->{time} = sprintf "%.4fs", $_->{time} for values ($_->{results} // [])
+       }
+};
+
+1
diff --git a/lib/Gruntmaster/Page/Log/Entry.pm b/lib/Gruntmaster/Page/Log/Entry.pm
deleted file mode 100644 (file)
index 57591b5..0000000
+++ /dev/null
@@ -1,29 +0,0 @@
-package Gruntmaster::Page::Log::Entry;
-
-use 5.014000;
-use strict;
-use warnings;
-use Gruntmaster::Page::Base log_entry => 'Job <tmpl_var id>';
-our @ISA = qw/Gruntmaster::Page::Base/;
-our $VERSION = '0.001';
-
-sub _generate{
-       my ($self, $htc, $lang, $env, $ct, $id) = @_;
-       debug $env => "language is '$lang', contest is '$ct' and id is '$id'";
-       local $Gruntmaster::Data::contest = $ct if $ct;
-
-       my @tests = ();
-
-       eval {
-               @tests = map {
-                       $_->{time} = sprintf "%.4fs", $_->{time};
-                       $_
-               } @{job_results $id};
-       };
-
-       $htc->param(id => $id);
-       $htc->param(tests => \@tests);
-       $htc->param(errors => job_errors $id)
-}
-
-1
diff --git a/lib/Gruntmaster/Page/Pb.pm b/lib/Gruntmaster/Page/Pb.pm
deleted file mode 100644 (file)
index ba78869..0000000
+++ /dev/null
@@ -1,27 +0,0 @@
-package Gruntmaster::Page::Pb;
-
-use 5.014000;
-use strict;
-use warnings;
-use Gruntmaster::Page::Base pb => 'Problems';
-our @ISA = qw/Gruntmaster::Page::Base/;
-our $VERSION = '0.001';
-
-sub _generate{
-       my ($self, $htc, $lang, $env, $ct) = @_;
-       debug $env => "language is '$lang' and contest is '$ct'";
-       local $Gruntmaster::Data::contest = $ct if $ct;
-
-       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);
-}
-
-1
diff --git a/lib/Gruntmaster/Page/Us.pm b/lib/Gruntmaster/Page/Us.pm
deleted file mode 100644 (file)
index 915ee50..0000000
+++ /dev/null
@@ -1,19 +0,0 @@
-package Gruntmaster::Page::Us;
-
-use 5.014000;
-use strict;
-use warnings;
-use Gruntmaster::Page::Base us => 'Users';
-our @ISA = qw/Gruntmaster::Page::Base/;
-our $VERSION = '0.001';
-
-sub _generate{
-       my ($self, $htc, $lang, $env) = @_;
-       debug $env => "language is '$lang'";
-
-       $htc->param(users => [ sort { lc $a->{name} cmp lc $b->{name} }
-                                                        map { {id => $_, name => user_name} }
-                                                          grep { user_name =~ /\w/ } users ]);
-}
-
-1
diff --git a/lib/Gruntmaster/Page/Us/Entry.pm b/lib/Gruntmaster/Page/Us/Entry.pm
deleted file mode 100644 (file)
index 628f9fa..0000000
+++ /dev/null
@@ -1,21 +0,0 @@
-package Gruntmaster::Page::Us::Entry;
-
-use 5.014000;
-use strict;
-use warnings;
-use Gruntmaster::Page::Base us_entry => '<tmpl_var name>';
-our @ISA = qw/Gruntmaster::Page::Base/;
-our $VERSION = '0.001';
-
-sub _generate{
-       my ($self, $htc, $lang, $env, $us) = @_;
-       debug $env => "language is '$lang', user is '$us'";
-       local $_ = $us;
-
-       $htc->param(name => user_name);
-       $htc->param(town => user_town);
-       $htc->param(university => user_university);
-       $htc->param(level => user_level);
-}
-
-1
index a0711013f99fec760e5b36f50cb8f77ce495da7e..131b7542bcf99f7ded495590527392bcdf6dff5f 100644 (file)
@@ -10,6 +10,9 @@ our $VERSION = '5999.000_001';
 use File::Slurp qw/read_file/;
 use HTTP::Negotiate qw/choose/;
 use Plack::Request;
+use Gruntmaster::Page::Log;
+use Gruntmaster::Page::Pb::Entry;
+use Gruntmaster::Page::Generic;
 
 my %handlers;
 
index 45cd40555a230dcea4d9b879f78acf4ccee69c64..35725c7feb0f0c08b5eca57dfb019898f5557905 100644 (file)
@@ -1,11 +1,15 @@
-Compiler output:
+<tmpl_if errors>
+<h2>Compiler output</h2>
 <pre><tmpl_var errors></pre>
+</tmpl_if>
 
-Results:
+<tmpl_if results>
+<h2>Results</h2>
 <table border class="table table-border table-striped">
 <thead>
 <tr><th>Test number<th>Result<th>Time
 <tbody>
-<tmpl_loop tests><tr><td><tmpl_var id><td class="r<tmpl_var result>"><tmpl_var result_text><td><tmpl_var time>
+<tmpl_loop results><tr><td><tmpl_var id><td class="r<tmpl_var result>"><tmpl_var result_text><td><tmpl_var time>
 </tmpl_loop>
 </table>
+</tmpl_if>
\ No newline at end of file
index 3a8194f6c0115b9bc46cc3d614a21bc22e6430d4..60205b1de2ee051fa2189495672362b4828fab6e 100644 (file)
@@ -1,26 +1,27 @@
-<tmpl_if levels>
+<tmpl_if beginner>
 <h2>Beginner</h2>
 <div class="list-group">
 <tmpl_loop beginner><a class="list-group-item" href="<tmpl_var id>"><tmpl_var name></a>
 </tmpl_loop></div>
+</tmpl_if>
 
+<tmpl_if beginner>
 <h2>Easy</h2>
 <div class="list-group">
 <tmpl_loop easy><a class="list-group-item" href="<tmpl_var id>"><tmpl_var name></a>
 </tmpl_loop></div>
+</tmpl_if>
 
+<tmpl_if beginner>
 <h2>Medium</h2>
 <div class="list-group">
 <tmpl_loop medium><a class="list-group-item" href="<tmpl_var id>"><tmpl_var name></a>
 </tmpl_loop></div>
+</tmpl_if>
 
+<tmpl_if beginner>
 <h2>Hard</h2>
 <div class="list-group">
 <tmpl_loop hard><a class="list-group-item" href="<tmpl_var id>"><tmpl_var name></a>
 </tmpl_loop></div>
-
-<tmpl_else>
-<div class="list-group">
-<tmpl_loop problems><a class="list-group-item" href="<tmpl_var id>"><tmpl_var name></a>
-</tmpl_loop></div>
 </tmpl_if>
index 174bc8009e3b16e201b922bab243c0965a61e2e0..72c72c35876e08c33949a874f049d3765ebc2f4b 100644 (file)
@@ -1,2 +1,2 @@
-<div class="list-group"><tmpl_loop users><a class="list-group-item" href="<tmpl_var id>"><tmpl_var name></a>
+<div class="list-group"><tmpl_loop us><a class="list-group-item" href="<tmpl_var id>"><tmpl_var name></a>
 </tmpl_loop></ol>
This page took 0.022364 seconds and 4 git commands to generate.