X-Git-Url: http://git.ieval.ro/?a=blobdiff_plain;f=lib%2FGruntmaster%2FPage%2FGeneric.pm;fp=lib%2FGruntmaster%2FPage%2FGeneric.pm;h=37e793105b1de231c1b04ce024e01baebb833318;hb=fdbf59e5def9cbb4e1c0749f819ba8d946c37725;hp=0000000000000000000000000000000000000000;hpb=b7bd0bad53df03baf5dc302ade58bea4f73d0880;p=plack-app-gruntmaster.git diff --git a/lib/Gruntmaster/Page/Generic.pm b/lib/Gruntmaster/Page/Generic.pm new file mode 100644 index 0000000..37e7931 --- /dev/null +++ b/lib/Gruntmaster/Page/Generic.pm @@ -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", ''; +} + +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