use Encode qw/encode decode/;
use File::Slurp qw/read_file/;
use JSON::MaybeXS qw/encode_json/;
+use List::Util qw/min/;
use PerlX::Maybe;
use Scope::Upper qw/unwind SUB UP/;
use Web::Simple;
sub redirect { [301, ['X-Forever' => 1, 'Cache-Control' => 'public, max-age=86400', 'Location' => $_[0]], []] }
sub reply { [200, ['Content-Type' => 'text/plain; charset=utf-8'], \@_] }
sub response {
- my ($template, $title, $params, $maxage) = @_;
+ my ($template, $title, $params, $maxage, $smaxage) = @_;
unless ($params) {
$params = $title;
$title = 'No title';
}
$params->{time} = time;
$params->{args} = {%_};
- bless {template => $template, title => $title, params => $params, maxage => ($maxage // 3600)}, __PACKAGE__.'::Response'
+ bless {template => $template, title => $title, params => $params, maxage => ($maxage // 3600), maybe smaxage => $smaxage}, __PACKAGE__.'::Response'
}
sub forbid {
response_filter {
my ($r) = @_;
return $r if ref $r ne 'Plack::App::Gruntmaster::Response';
- my @hdrs = ('X-Forever' => 1, 'Cache-Control' => "$privacy, max-age=$r->{maxage}");
+ my $smaxage = $r->{smaxage} ? ", s-maxage=$r->{smaxage}" : '';
+ my @hdrs = ('Cache-Control' => "$privacy$smaxage, max-age=$r->{maxage}");
+ push @hdrs, 'X-Forever' => 1 unless $smaxage;
push @hdrs, Vary => 'Authorization' if $privacy eq 'private';
return [200, ['Content-Type' => 'application/json; charset=utf-8', @hdrs], [encode_json $r->{params}]] if $format eq 'json';
my $ret = render $r->{template}, 'en', title => $r->{title}, %{$r->{params}};
sub (/ct/:contest/log/st) { redirect "/st/$_{contest}" },
sub (/us/) { response us => 'Users', {us => user_list} },
- sub (/ct/ + ?:owner~) { response ct => 'Contests', {ct => contest_list(%_)}, 300 },
+ sub (/ct/ + ?:owner~) {
+ my $cts = contest_list(%_);
+ my $first_event = min
+ map ({ $_->{start} } grep { !$_->{started} } @$cts),
+ map ({ $_->{stop} } grep { $_->{started} && !$_->{finished}} @$cts);
+ response ct => 'Contests', {ct => $cts}, 300, $first_event ? ($first_event - time) : ();
+ },
sub (/log/ + ?:contest~&:owner~&:page~&:problem~&:private~&:result~) {
forbid $_{private};
my ($jobs, $pageinfo) = job_list(%_);
},
sub (/ct/:contest) {
my $contest = contest_entry $_{contest};
- response ct_entry => $contest->{name}, $contest, 60
+ my $smaxage;
+ $smaxage = $contest->{start} - time if !$contest->{started};
+ $smaxage = $contest->{stop} - time if $contest->{started} && !$contest->{finished};
+ response ct_entry => $contest->{name}, $contest, 60, $smaxage ? ($smaxage) : ()
},
sub (/log/:job) {
my $job = job_entry $_{job};