]> iEval git - gruntmaster-page.git/blobdiff - lib/Gruntmaster/Page/Generic.pm
Introduce Gruntmaster::Page::Generic
[gruntmaster-page.git] / lib / Gruntmaster / Page / Generic.pm
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
This page took 0.026159 seconds and 4 git commands to generate.