<div id="title"><span class="i">i</span><span class="Eval">Eval</span></div>
<div id="subtitle">TITLE_GOES_HERE</div>
-<nav><ul><li><a href="/">Home</a><li><a href="/log/">View job log</a><li><a href="/submit.var">Submit job</a><li><a href="/pb/">Problem list</a></ul></nav>
+<nav><ul><li><a href="/">Home</a><li><a href="/log/">View job log</a><li><a href="/submit.var">Submit job</a><li><a href="/pb/">Problem list</a><li><a href="/ct/">Contests</a></ul></nav>
HTML
);
push @generators, [$regex, $gensub];
}
-declaregen Index => qr'^index$';
-declaregen Log => qr'^log/index$';
-declaregen 'Log::Entry' => qr'^log/.*/index$';
-declaregen Submit => qr'^submit$';
-declaregen Pb => qr'^pb/index$';
-declaregen 'Pb::Entry' => qr'^pb/.*/index$';
+{
+ 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/st/index$,;
+ 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$,;
+}
sub generate{
my ($path) = @_;
--- /dev/null
+package Gruntmaster::Page::Ct;
+
+use 5.014000;
+use strict;
+use warnings;
+use parent qw/Exporter/;
+our @EXPORT_OK = qw/generate/;
+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 qw/header footer/;
+
+my %templates = (
+ en => <<'HTML',
+<tmpl_if runningn>
+<h1>Running contests</h1>
+<table border>
+<thead>
+<tr><th>Name<th>Start date<th>End date<th>Owner
+<tbody>
+<tmpl_loop running><tr><td><a href="<tmpl_var id>"><tmpl_var name></a>
+<td><tmpl_var start>
+<td><tmpl_var end>
+<td><tmpl_var owner>
+</tmpl_loop>
+</table>
+</tmpl_if>
+
+<tmpl_if pendingn>
+<h1>Pending contests</h1>
+<table border>
+<thead>
+<tr><th>Name<th>Start date<th>End date<th>Owner
+<tbody>
+<tmpl_loop pending><tr><td><a href="<tmpl_var id>"><tmpl_var name></a>
+<td><tmpl_var start>
+<td><tmpl_var end>
+<td><tmpl_var owner>
+</tmpl_loop>
+</table>
+</tmpl_if>
+
+<tmpl_if finishedn>
+<h1>Finished contests</h1>
+<table border>
+<thead>
+<tr><th>Name<th>Start date<th>End date<th>Owner
+<tbody>
+<tmpl_loop finished><tr><td><a href="<tmpl_var id>"><tmpl_var name></a>
+<td><tmpl_var start>
+<td><tmpl_var end>
+<td><tmpl_var owner>
+</tmpl_loop>
+</table>
+</tmpl_if>
+HTML
+);
+
+$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('<ct/meta.yml'), LOCK_SH;
+
+ my (@running, @pending, @finished);
+ for (<ct/*/meta.yml>) {
+ 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 $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};
+ }
+
+ $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
+}
+
+1
--- /dev/null
+package Gruntmaster::Page::Ct::Entry;
+
+use 5.014000;
+use strict;
+use warnings;
+use parent qw/Exporter/;
+our @EXPORT_OK = qw/generate/;
+our $VERSION = '0.001';
+
+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 qw/header footer/;
+
+use constant TITLE => '<tmpl_var name>';
+
+my %templates = (
+ en => <<'HTML',
+Contest start time: <tmpl_var start><br>
+Contest end time: <tmpl_var end><p>
+
+<tmpl_if started><a href="pb/">Problems</a><br>
+<a href="log/">Job log</a><br>
+<a href="st/">Standings</a></tmpl_if>
+HTML
+);
+
+$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("<ct/$path/meta.yml"), LOCK_SH;
+ my $meta = LoadFile "ct/$path/meta.yml";
+
+ $htc->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
+}
+
+1
$templates{$_} .= footer $_ for keys %templates;
sub generate{
- my $template = $templates{$_[1]};
+ my ($path, $lang) = @_;
+ $path =~ s,/index\.html$,,;
+ my $template = $templates{$lang};
my $htc = HTML::Template::Compiled->new(scalarref => \$template);
- IO::File->new('>log/meta.yml')->close unless -f 'log/meta.yml';
- flock my $metafh = IO::File->new('<log/meta.yml'), LOCK_SH;
- my $meta = LoadFile 'log/meta.yml';
+ 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 "log/$_/meta.yml";
+ my $meta = LoadFile "$path/$_/meta.yml";
+{ id => $_,
date => strftime ('%c' => localtime $meta->{date}),
user => $meta->{user},
problem => $meta->{problem},
filename => $meta->{files}{prog}{name},
(defined $meta->{private} ? (private => $meta->{private}) : ()),
- size => sprintf ("%.2f KiB", (-s "log/$_/in/" . $meta->{files}{prog}{name}) / 1024),
+ 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
sub generate{
my ($path, $lang) = @_;
- $path = ($path =~ m,log/(.*)/index,)[0];
+ $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("<log/$path/meta.yml"), LOCK_SH;
- my $meta = LoadFile "log/$path/meta.yml";
+ 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 => $path);
+ $htc->param(id => $id);
$htc->param(tests => \@tests);
$htc->output
}
$templates{$_} .= footer $_ for keys %templates;
sub generate{
- my $template = $templates{$_[1]};
+ my ($path, $lang) = @_;
+ $path =~ s,/index\.html$,,;
+ my $template = $templates{$lang};
my $htc = HTML::Template::Compiled->new(scalarref => \$template);
- IO::File->new('>pb/meta.yml')->close unless -f 'pb/meta.yml';
- flock my $metafh = IO::File->new('<pb/meta.yml'), LOCK_SH;
+ 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,^pb/(.*)/meta.yml$,)[0];
- +{ id => $id, name => $meta->{name} } } <pb/*/meta.yml>;
+ my $id = (m,^$path/(.*)/meta.yml$,)[0];
+ +{ id => $id, name => $meta->{name} } } <$path/*/meta.yml>;
$htc->param(problems => \@problems);
$htc->output
}
en => <<'HTML',
<tmpl_var statement>
+<tmpl_if cansubmit>
<h1>Submit solution</h1>
<form action="https://gm.ieval.ro/action/submit" method="POST" enctype="multipart/form-data">
<input type="hidden" name="problem" value="<tmpl_var id>">
+<tmpl_if_defined contest><input type="hidden" name="contest" value="<tmpl_var contest>"></tmpl_if_defined>
<label>File: <input name="prog" required type="file"></label>
<label>File format: <select name="prog_format" required>
</tmpl_loop></select></label>
<input type="submit" value="Submit job">
+</tmpl_if>
HTML
);
sub generate{
my ($path, $lang) = @_;
- $path = ($path =~ m,pb/(.*)/index,)[0];
+ 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("<pb/$path/meta.yml"), LOCK_SH;
- my $meta = LoadFile "pb/$path/meta.yml";
+ flock my $metafh = IO::File->new("<$path/meta.yml"), LOCK_SH;
+ my $meta = LoadFile "$path/meta.yml";
+ $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 => $path);
+ $htc->param(id => $id);
$htc->param(name => $meta->{name});
- $htc->param(statement => scalar slurp "pb/$path/statement.$lang");
+ $htc->param(statement => scalar slurp "$path/statement.$lang");
$htc->output
}