From: Marius Gavrilescu Date: Wed, 8 Jan 2014 15:44:27 +0000 (+0200) Subject: Use Redis and reindent code X-Git-Url: http://git.ieval.ro/?a=commitdiff_plain;h=cd9af27e94244e6454c3db787a8ca6811f44fc16;p=gruntmaster-page.git Use Redis and reindent code --- diff --git a/lib/Gruntmaster/Data.pm b/lib/Gruntmaster/Data.pm new file mode 100644 index 0000000..f9162af --- /dev/null +++ b/lib/Gruntmaster/Data.pm @@ -0,0 +1,65 @@ +package Gruntmaster::Data; +use v5.14; +use warnings; +use parent qw/Exporter/; + +use JSON qw/encode_json decode_json/; + +use Redis; + +our $contest; +my $redis = Redis->new; + +sub dynsub{ + no strict 'refs'; + *{$_[0]} = $_[1]; +} + +BEGIN { + for my $cmd (qw/multi exec smembers get hget hset sadd incr hmset/) { + dynsub uc $cmd, sub { say $cmd;exit;$redis->$cmd(@_) }; + } +} + +sub cp { defined $contest ? "contest.$contest." : '' } + +sub multi () { MULTI } +sub rexec () { EXEC } + +sub problems () { SMEMBERS cp . 'problem' } +sub contests () { SMEMBERS cp . 'contest' } +sub jobcard () { GET cp . 'job' } + +sub job_results (_) { decode_json HGET cp . "job.$_[0]", 'results' } +sub set_job_results ($+) { HSET cp . "job.$_[0]", 'results', encode_json $_[1] } +sub problem_meta (_) { decode_json HGET cp . "pb.$_[0]", 'meta' } +sub set_problem_meta ($+) { HSET cp . "pb.$_[0]", 'meta', encode_json $_[1] } + +sub defhash{ + my ($name, @keys) = @_; + for my $key (@keys) { + dynsub "${name}_$key", sub (_) { HGET cp . "$name.$_[0]", $key }; + dynsub "set_${name}_$key", sub ($$) { HSET cp . "$name.$_[0]", $key, $_[1] }; + } + + dynsub "insert_$name", sub { + my ($key, %values) = @_; + SADD cp . $name, $key or return; + HMSET cp . "$name.$key", %values; + }; + dynsub "push_$name", sub { + my $nr = INCR cp . $name; + HMSET cp . "$name.$nr", @_; + }; +} + +defhash problem => qw/name level statement/; +defhash contest => qw/start end name owner/; +defhash job => qw/date file name private problem result result_text user/; + +our @EXPORT_OK = do { + no strict 'refs'; + grep { $_ =~ /^[a-z]/ and exists &$_ } keys %{__PACKAGE__ . '::'}; +}; + +1 diff --git a/lib/Gruntmaster/Page.pm b/lib/Gruntmaster/Page.pm index a07a102..6ca62dd 100644 --- a/lib/Gruntmaster/Page.pm +++ b/lib/Gruntmaster/Page.pm @@ -17,60 +17,60 @@ our @generators; use constant LANGUAGES => [ 'en' ]; use constant CONTENT_TYPES => { - html => 'text/html; charset=UTF-8', - txt => 'text/plain; charset=UTF-8', + html => 'text/html; charset=UTF-8', + txt => 'text/plain; charset=UTF-8', }; 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]; + 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]; } { - my $component = qr'[^/]+'; - my $contest = qr,(?:ct/$component/)?,; - declaregen Index => qr,^index$,; - declaregen Ct => qr,^ct/index$,; - declaregen 'Ct::Entry' => qr,^ct/$component/index$,; - declaregen St => qr,^ct/$component/log/st$,; - declaregen Learn => qr,^learn$,; - declaregen Log => qr,^${contest}log/index$,; - declaregen 'Log::Entry' => qr,^${contest}log/$component/index$,; - declaregen Submit => qr,^${contest}submit$,; - declaregen Pb => qr,^${contest}pb/index$,; - declaregen 'Pb::Entry' => qr,^${contest}pb/$component/index$,; + my $component = qr'[^/]+'; + my $contest = qr,(?:ct/$component/)?,; + declaregen Index => qr,^index$,; + declaregen Learn => qr,^learn$,; + declaregen Ct => qr,^ct/index$,; + declaregen 'Ct::Entry' => qr,^ct/$component/index$,; + declaregen St => qr,^ct/$component/log/st$,; + declaregen Log => qr,^${contest}log/(?:\d+|index)$,; + declaregen 'Log::Entry' => qr,^${contest}log/$component/index$,; + declaregen Submit => qr,^${contest}submit$,; + declaregen Pb => qr,^${contest}pb/index$,; + declaregen 'Pb::Entry' => qr,^${contest}pb/$component/index$,; } sub generate{ - my ($path) = @_; - my ($path_noext, $ext) = $path =~ m/^(.*)\.(.*)$/; - my $basename = fileparse $path_noext; - - IO::File->new(">$path_noext.var")->close unless -f "$path_noext.var"; - flock my $lockfh = IO::File->new("<$path_noext.var"), LOCK_EX; - open my $typemap, ">$path_noext.var.new"; - say $typemap "URI: $basename\n"; - for my $gen(@generators) { - my ($regex, $generator) = @$gen; - next unless $path_noext =~ $regex; + my ($path) = @_; + my ($path_noext, $ext) = $path =~ m/^(.*)\.(.*)$/; + my $basename = fileparse $path_noext; + + IO::File->new(">$path_noext.var")->close unless -f "$path_noext.var"; + flock my $lockfh = IO::File->new("<$path_noext.var"), LOCK_EX; + open my $typemap, ">$path_noext.var.new"; + say $typemap "URI: $basename\n"; + for my $gen (@generators) { + my ($regex, $generator) = @$gen; + next unless $path_noext =~ $regex; + for my $lang (@{LANGUAGES()}) { + my $page = $generator->($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; + say $typemap "URI: $basename.$lang.gz.$ext\nContent-Language: $lang\nContent-Encoding: gzip\nContent-Type: " . CONTENT_TYPES->{$ext} . "\n"; + } + } + for my $lang (@{LANGUAGES()}) { - my $page = $generator->($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; - say $typemap "URI: $basename.$lang.gz.$ext\nContent-Language: $lang\nContent-Encoding: gzip\nContent-Type: " . CONTENT_TYPES->{$ext} . "\n"; + rename "$path_noext.$lang.$ext.new", "$path_noext.$lang.$ext"; + rename "$path_noext.$lang.gz.$ext.new", "$path_noext.$lang.gz.$ext"; } - } - - for my $lang(@{LANGUAGES()}) { - rename "$path_noext.$lang.$ext.new", "$path_noext.$lang.$ext"; - rename "$path_noext.$lang.gz.$ext.new", "$path_noext.$lang.gz.$ext"; - } - rename "$path_noext.var.new", "$path_noext.var"; - close $typemap; + rename "$path_noext.var.new", "$path_noext.var"; + close $typemap; } 1; diff --git a/lib/Gruntmaster/Page/Ct.pm b/lib/Gruntmaster/Page/Ct.pm index 5a04b3a..19c4aad 100644 --- a/lib/Gruntmaster/Page/Ct.pm +++ b/lib/Gruntmaster/Page/Ct.pm @@ -9,16 +9,14 @@ our $VERSION = '0.001'; use constant TITLE => 'Contests'; -use Fcntl qw/:flock/; use HTML::Template::Compiled; -use IO::File; use POSIX qw/strftime/; -use YAML::Any qw/LoadFile/; use Gruntmaster::Page::Common qw/header footer/; +use Gruntmaster::Data qw/contest_name contest_start contest_end contest_owner/; my %templates = ( - en => <<'HTML', - + en => <<'HTML', +

Running contests

@@ -32,7 +30,7 @@ my %templates = (
- +

Pending contests

@@ -46,7 +44,7 @@ my %templates = (
- +

Finished contests

@@ -66,34 +64,26 @@ $templates{$_} = header($_, TITLE) . $templates{$_} for keys %templates; $templates{$_} .= footer $_ for keys %templates; sub generate{ - my $template = $templates{$_[1]}; - my $htc = HTML::Template::Compiled->new(scalarref => \$template); - IO::File->new('>ct/meta.yml')->close unless -f 'ct/meta.yml'; - flock my $metafh = IO::File->new('new(scalarref => \$templates{$_[1]}); - my (@running, @pending, @finished); - for () { - my $meta = LoadFile $_; - my $id = (m,^ct/(.*)/meta.yml$,)[0]; - my $ct = { id => $id, - name => $meta->{name}, - start => strftime ('%c', localtime $meta->{start}), - end => strftime ('%c', localtime $meta->{end}), - owner => $meta->{owner}}; + my (@running, @pending, @finished); + for (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 < $meta->{start}; - push @running, $ct if time >= $meta->{start} && time < $meta->{end}; - push @finished, $ct if time > $meta->{end}; - } + 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(runningn => scalar @running); - $htc->param(pendingn => scalar @pending); - $htc->param(finishedn => scalar @finished); - $htc->param(running => \@running); - $htc->param(pending => \@pending); - $htc->param(finished => \@finished); - $htc->output + $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 725e3e9..3c336c1 100644 --- a/lib/Gruntmaster/Page/Ct/Entry.pm +++ b/lib/Gruntmaster/Page/Ct/Entry.pm @@ -7,19 +7,15 @@ use parent qw/Exporter/; our @EXPORT_OK = qw/generate/; our $VERSION = '0.001'; -use Fcntl qw/:flock/; +use constant TITLE => ''; + use HTML::Template::Compiled; -use IO::File; use POSIX qw/strftime/; -use YAML::Any qw/LoadFile/; -use File::Basename qw/fileparse/; -use File::Slurp qw/slurp/; use Gruntmaster::Page::Common qw/header footer/; - -use constant TITLE => ''; +use Gruntmaster::Data qw/contest_name contest_start contest_end/; my %templates = ( - en => <<'HTML', + en => <<'HTML', Contest start time:
Contest end time:

@@ -33,19 +29,17 @@ $templates{$_} = header($_, TITLE) . $templates{$_} for keys %templates; $templates{$_} .= footer $_ for keys %templates; sub generate{ - my ($path, $lang) = @_; - $path = ($path =~ m,ct/(.*)/index,)[0]; - my $template = $templates{$lang}; - my $htc = HTML::Template::Compiled->new(scalarref => \$template); - flock my $metafh = IO::File->new("param(id => $path); - $htc->param(name => $meta->{name}); - $htc->param(start => strftime '%c', localtime $meta->{start}); - $htc->param(end => strftime '%c', localtime $meta->{end}); - $htc->param(started => time >= $meta->{start}); - $htc->output + 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 604be12..4f20bac 100644 --- a/lib/Gruntmaster/Page/Index.pm +++ b/lib/Gruntmaster/Page/Index.pm @@ -9,9 +9,7 @@ our $VERSION = '0.001'; use constant TITLE => 'Gruntmaster 6000'; -use Fcntl qw/:flock/; use HTML::Template::Compiled; -use IO::File; use Gruntmaster::Page::Common qw/header footer/; my %templates = ( @@ -23,11 +21,7 @@ $templates{$_} = header($_, TITLE) . $templates{$_} for keys %templates; $templates{$_} .= footer $_ for keys %templates; sub generate{ - my $template = $templates{$_[1]}; - my $htc = HTML::Template::Compiled->new(scalarref => \$template); - IO::File->new('>meta.yml')->close unless -f 'meta.yml'; - flock my $metafh = IO::File->new('output + HTML::Template::Compiled->new(scalarref => \$templates{$_[1]})->output } 1 diff --git a/lib/Gruntmaster/Page/Learn.pm b/lib/Gruntmaster/Page/Learn.pm index 8fce8c8..1ba2e4e 100644 --- a/lib/Gruntmaster/Page/Learn.pm +++ b/lib/Gruntmaster/Page/Learn.pm @@ -7,19 +7,15 @@ use parent qw/Exporter/; our @EXPORT_OK = qw/generate/; our $VERSION = '0.001'; -use constant FORMATS => [qw/CPP/]; -use constant TITLE => 'Learn Perl'; +use constant TITLE => 'Learn'; -use Fcntl qw/:flock/; use HTML::Template::Compiled; -use IO::File; -use YAML::Any qw/LoadFile/; use Gruntmaster::Page::Common qw/header footer/; my %templates = ( en => <<'HTML', -Download interactive-perl-tutorial for Linux | Windows | Mac OS X. -

Get the source from meta::cpan +Install interactive-perl-tutorial from your nearest CPAN mirror. Run cpan App::InteractivePerlTutorial. +

You can also get the source from git.ieval.ro HTML ); @@ -27,9 +23,7 @@ $templates{$_} = header($_, TITLE) . $templates{$_} for keys %templates; $templates{$_} .= footer $_ for keys %templates; sub generate{ - my $template = $templates{$_[1]}; - my $htc = HTML::Template::Compiled->new(scalarref => \$template); - $htc->output + HTML::Template::Compiled->new(scalarref => \$templates{$_[1]})->output; } 1 diff --git a/lib/Gruntmaster/Page/Log.pm b/lib/Gruntmaster/Page/Log.pm index c92bf4d..a86b153 100644 --- a/lib/Gruntmaster/Page/Log.pm +++ b/lib/Gruntmaster/Page/Log.pm @@ -8,16 +8,15 @@ our @EXPORT_OK = qw/generate/; our $VERSION = '0.001'; use constant TITLE => 'Job log'; +use constant PAGE_SIZE => 10; -use Fcntl qw/:flock/; use HTML::Template::Compiled; -use IO::File; use POSIX qw/strftime/; -use YAML::Any qw/LoadFile/; use Gruntmaster::Page::Common qw/header footer/; +use Gruntmaster::Data qw/job_date job_file job_name job_private job_problem job_result job_result_text job_user/; my %templates = ( - en => <<'HTML', + en => <<'HTML',

IDProblemDateSizeUserResult @@ -25,7 +24,7 @@ my %templates = (
- data-private> +
@@ -36,27 +35,23 @@ $templates{$_} = header($_, TITLE) . $templates{$_} for keys %templates; $templates{$_} .= footer $_ for keys %templates; sub generate{ - my ($path, $lang) = @_; - $path =~ s,/index\.html$,,; - my $template = $templates{$lang}; - my $htc = HTML::Template::Compiled->new(scalarref => \$template); - IO::File->new(">$path/meta.yml")->close unless -f "$path/meta.yml"; - flock my $metafh = IO::File->new("<$path/meta.yml"), LOCK_SH; - my $meta = LoadFile "$path/meta.yml"; - my @log = sort { $b->{id} <=> $a->{id} } map { - my $meta = LoadFile "$path/$_/meta.yml"; - +{ id => $_, - date => (exists $meta->{date} ? strftime ('%c' => localtime $meta->{date}) : '?'), - user => $meta->{user}, - result => $meta->{result}, - name => $meta->{name}, - problem => $meta->{problem}, - filename => $meta->{files}{prog}{name}, - (defined $meta->{private} ? (private => $meta->{private}) : ()), - size => sprintf ("%.2f KiB", (-s "$path/$_/in/" . $meta->{files}{prog}{name}) / 1024), - result_text => $meta->{result_text}} } 1 .. $meta->{last}; - $htc->param(log => \@log); - $htc->output + $_[0] =~ m,^(?:ct/([^/]+)/)?log/(\w+)\.html$,; + local $Gruntmaster::Data::contest = $1; + my $page = $2 eq 'index' ? 0 : $2; + + my $htc = HTML::Template::Compiled->new(scalarref => \$templates{$_[1]}); + my @log = sort { $b->{id} <=> $a->{id} } map +{ + id => $_, + (job_private() ? (private => job_private) : ()), + date => (job_date() ? strftime ('%c' => localtime job_date) : '?'), + name => job_name, + problem => job_problem, + result => job_result, + result_text => job_result_text, + size => sprintf ("%.2f KiB", (length job_file) / 1024), + user => job_user}, ($page - 1) * PAGE_SIZE + 1 .. $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 e849876..309660a 100644 --- a/lib/Gruntmaster/Page/Log/Entry.pm +++ b/lib/Gruntmaster/Page/Log/Entry.pm @@ -9,15 +9,13 @@ our $VERSION = '0.001'; use constant TITLE => 'Job '; -use Fcntl qw/:flock/; use HTML::Template::Compiled; -use IO::File; use POSIX qw/strftime/; -use YAML::Any qw/LoadFile/; use Gruntmaster::Page::Common qw/header footer/; +use Gruntmaster::Data qw/job_results/; my %templates = ( - en => <<'HTML', + en => <<'HTML',
Test numberResultTime @@ -32,23 +30,20 @@ $templates{$_} = header($_, TITLE) . $templates{$_} for keys %templates; $templates{$_} .= footer $_ for keys %templates; sub generate{ - my ($path, $lang) = @_; - my $id = ($path =~ m,log/(.*)/index,)[0]; - $path =~ s,/index\.html,,; - my $template = $templates{$lang}; - - my $htc = HTML::Template::Compiled->new(scalarref => \$template); - flock my $metafh = IO::File->new("<$path/meta.yml"), LOCK_SH; - my $meta = LoadFile "$path/meta.yml"; - - my @tests = map { - $_->{time} = sprintf "%.4fs", $_->{time}; - $_ - } @{$meta->{results}}; - - $htc->param(id => $id); - $htc->param(tests => \@tests); - $htc->output + $_[0] =~ m,^(?:ct/([^/]+)/)?log/([^/]+)/index\.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}; + $_ + } @{job_results $id}; + + $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 0aae2b0..170f03f 100644 --- a/lib/Gruntmaster/Page/Pb.pm +++ b/lib/Gruntmaster/Page/Pb.pm @@ -13,8 +13,8 @@ use Fcntl qw/:flock/; use HTML::Template::Compiled; use IO::File; use POSIX qw/strftime/; -use YAML::Any qw/LoadFile/; use Gruntmaster::Page::Common qw/header footer/; +use Gruntmaster::Data qw/problem_name problem_level problems/; my %templates = ( en => <<'HTML', @@ -51,22 +51,20 @@ $templates{$_} = header($_, TITLE) . $templates{$_} for keys %templates; $templates{$_} .= footer $_ for keys %templates; sub generate{ - my ($path, $lang) = @_; - $path =~ s,/index\.html$,,; - my $template = $templates{$lang}; - my $htc = HTML::Template::Compiled->new(scalarref => \$template); - IO::File->new(">$path/meta.yml")->close unless -f "$path/meta.yml"; - flock my $metafh = IO::File->new("<$path/meta.yml"), LOCK_SH; - my @problems = sort { $b->{name} cmp $a->{name} } map { - my $meta = LoadFile $_; - my $id = (m,^$path/(.*)/meta.yml$,)[0]; - +{ id => $id, name => $meta->{name}, level => $meta->{level} } } <$path/*/meta.yml>; - 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 + $_[0] =~ 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 0e6bbc8..ebcf56e 100644 --- a/lib/Gruntmaster/Page/Pb/Entry.pm +++ b/lib/Gruntmaster/Page/Pb/Entry.pm @@ -11,16 +11,15 @@ use Fcntl qw/:flock/; use HTML::Template::Compiled; use IO::File; use POSIX qw/strftime/; -use YAML::Any qw/LoadFile/; use File::Basename qw/fileparse/; -use File::Slurp qw/slurp/; use Gruntmaster::Page::Common qw/header footer/; +use Gruntmaster::Data qw/contest_start contest_end problem_name problem_statement/; use constant FORMATS => [qw/CPP/]; use constant TITLE => ''; my %templates = ( - en => <<'HTML', + en => <<'HTML', @@ -44,27 +43,22 @@ $templates{$_} = header($_, TITLE) . $templates{$_} for keys %templates; $templates{$_} .= footer $_ for keys %templates; sub generate{ - my ($path, $lang) = @_; - my $contest; - $contest = $1 if $path =~ m,ct/([^/]*)/,; - my $id = ($path =~ m,pb/([^/]*)/index,)[0]; - $path =~ s,/index\.html$,,; - my $template = $templates{$_[1]}; - my $htc = HTML::Template::Compiled->new(scalarref => \$template); - flock my $metafh = IO::File->new("<$path/meta.yml"), LOCK_SH; - my $meta = LoadFile "$path/meta.yml"; + $_[0] =~ m,(?:ct/([^/])+/)?log/(\w+)\.html$,; - $htc->param(cansubmit => 1); - if (defined $contest) { - my $meta = LoadFile "ct/$contest/meta.yml"; - $htc->param(cansubmit => time >= $meta->{start} && time <= $meta->{end}); - $htc->param(contest => $contest); - } - $htc->param(formats => FORMATS); - $htc->param(id => $id); - $htc->param(name => $meta->{name}); - $htc->param(statement => scalar slurp "$path/statement.$lang"); - $htc->output + my ($contest, $id) = ($1, $2); + my $htc = HTML::Template::Compiled->new(scalarref => \$templates{$_[1]}); + + $htc->param(cansubmit => 1); + if (defined $contest) { + $htc->param(cansubmit => time >= contest_start $contest && time <= contest_end $contest); + $htc->param(contest => $contest); + } + $htc->param(formats => FORMATS); + $htc->param(id => $id); + local $Gruntmaster::Data::contest = ($_[0] =~ m,(?:ct/([^/])+/)?,)[0]; + $htc->param(name => problem_name $id); + $htc->param(statement => problem_statement $id, $_[2]); + $htc->output } 1 diff --git a/lib/Gruntmaster/Page/St.pm b/lib/Gruntmaster/Page/St.pm index f4d961e..e5b418d 100644 --- a/lib/Gruntmaster/Page/St.pm +++ b/lib/Gruntmaster/Page/St.pm @@ -9,16 +9,14 @@ our $VERSION = '0.001'; use constant TITLE => 'Standings'; -use Fcntl qw/:flock/; use HTML::Template::Compiled; -use IO::File; use List::Util qw/sum/; use POSIX qw/strftime/; -use YAML::Any qw/LoadFile/; use Gruntmaster::Page::Common qw/header footer/; +use Gruntmaster::Data qw/problems jobcard job_result_text job_result job_problem job_user/; my %templates = ( - en => <<'HTML', + en => <<'HTML',
UsernameTotal @@ -35,35 +33,30 @@ $templates{$_} = header($_, TITLE) . $templates{$_} for keys %templates; $templates{$_} .= footer $_ for keys %templates; sub generate{ - my ($path, $lang) = @_; - $path =~ s,/st\.html$,,; - my $template = $templates{$lang}; - my $htc = HTML::Template::Compiled->new(scalarref => \$template); - IO::File->new(">$path/meta.yml")->close unless -f "$path/meta.yml"; - flock my $metafh = IO::File->new("<$path/meta.yml"), LOCK_SH; - my $meta = LoadFile "$path/meta.yml"; - my @problems = sort grep { /^\w+$/ } map { s,.*/,,r } <$path/../pb/*>; - my %scores; - for (1 .. $meta->{last}) { - my $meta = LoadFile "$path/$_/meta.yml"; - if ($meta->{result_text} =~ m/^(\d+)/) { - $scores{$meta->{user}}{$meta->{problem}} = $1; - } else { - $scores{$meta->{user}}{$meta->{problem}} = $meta->{result} ? 0 : 100; + local $Gruntmaster::Data::contest = ($_[0] =~ m,^ct/([^/]+)/,)[0]; + my $htc = HTML::Template::Compiled->new(scalarref => \$templates{$_[1]}); + + my @problems = sort problems; + my %scores; + for (1 .. jobcard) { + if (job_result_text =~ m/^(\d+)/) { + $scores{job_user()}{job_problem()} = $1; + } else { + $scores{job_user()}{job_problem()} = job_result() ? 0 : 100; + } } - } - my @st = sort { $b->{score} <=> $a->{score} } map { - my $user = $_; - +{ - user => $user, - score => sum (values $scores{$user}), - scores => [map { $scores{$user}{$_} // '-'} @problems], - } - } keys %scores; - $htc->param(problems => \@problems); - $htc->param(st => \@st); - $htc->output + my @st = sort { $b->{score} <=> $a->{score} } map { + my $user = $_; + +{ + user => $user, + score => sum (values $scores{$user}), + scores => [map { $scores{$user}{$_} // '-'} @problems], + } + } 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 a57b7b1..3f289d5 100644 --- a/lib/Gruntmaster/Page/Submit.pm +++ b/lib/Gruntmaster/Page/Submit.pm @@ -12,12 +12,12 @@ use constant TITLE => 'Submit job'; use Fcntl qw/:flock/; use HTML::Template::Compiled; -use IO::File; use YAML::Any qw/LoadFile/; use Gruntmaster::Page::Common qw/header footer/; +use Gruntmaster::Data qw//; my %templates = ( - en => <<'HTML', + en => <<'HTML',