From: Marius Gavrilescu Date: Mon, 24 Mar 2014 19:10:08 +0000 (+0200) Subject: Merge branch 'master' into gruntmaster X-Git-Url: http://git.ieval.ro/?p=gruntmaster-page.git;a=commitdiff_plain;h=4cea7880b004110af3dcffcf01a5851eb7be042c;hp=8bf14b38c3ae61f4f5ef5ca6ce53e3895a9dc980 Merge branch 'master' into gruntmaster --- diff --git a/app.psgi b/app.psgi index e662e26..a661a31 100644 --- a/app.psgi +++ b/app.psgi @@ -25,17 +25,29 @@ sub debug { sub some_auth_required { my $r = Plack::Request->new($_[0]); - return 1 if $_[0]->{'gruntmaster.reqadmin'} || $r->path eq '/action/passwd' || $r->path =~ m,/pb/$word/submit$,; + return 1 if $_[0]->{'gruntmaster.reqadmin'} || $r->path eq '/action/passwd' || $r->path eq '/submit'; return 1 if $r->path =~ m,^/ct/$word/pb/$word, && time < $db->contest($1)->stop; '' } +sub is_problem_private { + my $pb = $_[0]; + return 1 if $db->problem($pb)->private; + my $prv = 0; + for my $cp ($db->problem($pb)->contest_problems) { + $prv = 1; + return '' if $cp->contest->start <= time; + } + + $prv +} + sub admin_required { local $_ = $_[0]; - return $db->problem($1)->owner if m,^/pb/$word, && $db->problem($1)->private; - return $db->job ($1)->owner if m,^/log/(?:job|src)/$word, && $db->job($1)->private; - return $db->contest($1)->owner if m,^/ct/$word/(?:pb|log), && time < $db->contest($1)->start; - return $db->job ($2)->owner if m,^/ct/$word/log/(?:job|src)/$word, && time < $db->contest($1)->stop; + my $env = $_[1]; + return $db->contest($1)->owner->id if $env->{'gruntmaster.contest'} && db->contest($env->{'gruntmaster.contest'})->start > time; + return $db->problem($1)->owner->id if m,^/pb/$word, && is_problem_private $1 || $env->{'gruntmaster.problem'} && is_problem_private $env->{'gruntmaster.problem'}; + return $db->job ($1)->owner->id if m,^/log/(?:src/)?$word, && ($db->job($1)->private || is_problem_private $db->job($1)->problem || $db->job($1)->contest && $db->contest($db->job($1)->contest)->start > time); '' } @@ -45,7 +57,7 @@ sub require_admin { local *__ANON__ = "require_admin_middleware"; my $env = $_[0]; my $r = Plack::Request->new($env); - $env->{'gruntmaster.reqadmin'} = admin_required $r->path; + $env->{'gruntmaster.reqadmin'} = admin_required $r->path, $env; $app->($env) } } @@ -91,6 +103,7 @@ sub authenticate { Log::Log4perl->init('log.conf'); my $access_logger = Log::Log4perl->get_logger('access'); +$ENV{DBIC_NULLABLE_KEY_NOWARN} = 1; builder { enable_if { $_[0]->{PATH_INFO} eq '/ok' } sub { sub{ [200, [], []] }}; @@ -100,9 +113,9 @@ builder { enable_if { $_[0]->{PATH_INFO} =~ qr,^/static/,} Header => set => ['Cache-Control', 'public, max-age=604800']; enable 'Static', path => qr,^/static/,; enable 'Log4perl', category => 'plack'; + enable \&mangle_request; enable \&require_admin; enable_if \&some_auth_required, 'Auth::Basic', authenticator => \&authenticate, realm => 'Gruntmaster 6000'; - enable \&mangle_request; enable sub { my $app = $_[0]; sub { $_[0]->{'gruntmaster.dbic'} = $db; $app->($_[0]) } }; Plack::App::Gruntmaster->to_app } diff --git a/lib/Gruntmaster/Page/Base.pm b/lib/Gruntmaster/Page/Base.pm index 0cae932..99ca432 100644 --- a/lib/Gruntmaster/Page/Base.pm +++ b/lib/Gruntmaster/Page/Base.pm @@ -88,7 +88,7 @@ sub generate{ my $htc = HTML::Template::Compiled->new(scalarref => \$templates{$self}{$lang}, default_escape => 'HTML', use_perl => 1); $self->_generate($htc, $lang, @args); my $out = $htc->output; - utf8::downgrade($out); + utf8::encode($out); my $vary = 'Accept-Language, ' . $self->vary; [200, ['Content-Type' => 'text/html', 'Content-Language' => $_[1], 'Vary' => $vary, 'X-Forever' => 1, 'Cache-Control' => 'max-age=' . $self->max_age], [ $out ] ] } diff --git a/lib/Gruntmaster/Page/Generic.pm b/lib/Gruntmaster/Page/Generic.pm index 10ed556..35d89ad 100644 --- a/lib/Gruntmaster/Page/Generic.pm +++ b/lib/Gruntmaster/Page/Generic.pm @@ -31,21 +31,25 @@ sub makepkg { sub list { my ($thing, $lang, $env) = @_; my %thing = %$thing; + my %params; #debug $env => "Contest is $ct"; $thing{makers} //= sub { db(shift)->resultset($thing{rsname}) }; my $rs = $thing{makers}->($env); $rs = $rs->search(undef, {order_by => 'me.id'}) unless $rs->is_ordered; if (my $page = $env->{'gruntmaster.page'}) { - my $pages = $rs->count / PAGE_SIZE; + my $pages = int ($rs->count / PAGE_SIZE); $page = $pages if $page == -1; + @params{'page', 'pages'} = ($page, $pages); $rs = $rs->search(undef, {offset => ($page - 1) * PAGE_SIZE, ($page == $pages ? () : (rows => PAGE_SIZE))}); } - $rs = $rs->search(undef, {prefetch => $thing{prefetch}}) if exists $thing{prefetch}; + $rs = $rs->search(undef, { + exists $thing{prefetch} ? (prefetch => $thing{prefetch}) : (), + exists $thing{columns} ? (columns => $thing{columns}) : (), + }); my @thing = map +{rs => $_, $_->get_columns}, $rs->all; @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}->(); @@ -59,8 +63,7 @@ sub entry { my ($thing, $lang, $env, $id) = @_; my %thing = %$thing; debug $env => "Rsname is $thing{rsname} and id is $id"; - $thing{makers} //= sub { db(shift)->resultset($thing{rsname}) }; - my %params = map {+ rs => $_, $_->get_columns } $thing{makers}->($env)->find($id); + my %params = map {+ rs => $_, $_->get_columns } db($env)->resultset($thing{rsname})->find($id); $thing{mangle}->(local $_ = \%params) if exists $thing{mangle}; wantarray ? %params : \%params } @@ -73,7 +76,7 @@ sub create_thing { my $pkg = "Gruntmaster::Page::$ucid"; putsym "${pkg}::_generate", sub { $_[1]->param(list \%thing, @_[2..$#_]) } if makepkg $pkg, @thing{qw/id title/}; - putsym "${pkg}::Entry::_generate", sub { $_[1]->param(entry \%thing, @_[2..$#_]) } if makepkg "${pkg}::Entry", "$thing{id}_entry", ''; + putsym "${pkg}::Entry::_generate", sub { $_[1]->param(entry \%thing, @_[2..$#_]) } if makepkg "${pkg}::Entry", "$thing{id}_entry", $thing{entry_title} // ''; putsym "${pkg}::Read::generate", sub { [200, headers shift, [encode_json list \%thing, @_]] } if makepkg "${pkg}::Read"; putsym "${pkg}::Entry::Read::generate", sub { [200, headers shift, [encode_json entry \%thing, @_]] } if makepkg "${pkg}::Entry::Read"; } @@ -85,17 +88,19 @@ sub sortby (&); sub group (&); sub mangle (&); sub prefetch; +sub columns; sub thing (&){ my %thing; no strict 'refs'; - local *{"params"} = sub { @thing{qw/id rsname title/} = @_ }; + local *{"params"} = sub { @thing{qw/id rsname title entry_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 *{"makers"} = sub { $thing{makers} = shift }; local *{"prefetch"} = sub { $thing{prefetch} = \@_ }; + local *{"columns"} = sub { $thing{columns} = \@_ }; use strict 'refs'; shift->(); @@ -116,23 +121,23 @@ thing { makers { my $env = $_[0]; my $db = db $env; - return $db->contest($env->{'gruntmaster.contest'})->problems->search(undef, {order_by => 'problem.id'}) if exists $env->{'gruntmaster.contest'}; return $db->problems->search({owner => $env->{'gruntmaster.user'}}) if exists $env->{'gruntmaster.user'}; - $db->problems->search({private => 0}); + return $db->problems->search({'contest_problems.contest' => $env->{'gruntmaster.contest'}}, {join => 'contest_problems'}) if exists $env->{'gruntmaster.contest'}; + $db->problems->search({-or => ['contest_problems.contest' => undef, 'contest.stop' => {'<=', time}], 'me.private' => 0}, {join => {'contest_problems' => 'contest'}}); }; sortby { $a->{name} cmp $b->{name}}; group { $_->{level} }; mangle { my $env = shift; $_->{owner_name} = $_->{rs}->owner->name; - $_->{cansubmit} = $_->{contest} ? time < $_->{rs}->contest->stop : 1; + $_->{cansubmit} = $env->{'gruntmaster.contest'} ? time < db($env)->contest($env->{'gruntmaster.contest'})->stop : 1; eval { db($env)->open->create({ - contest => $_->{contest}, + contest => $env->{'gruntmaster.contest'}, problem => $_->{id}, owner => $env->{REMOTE_USER}, }) - } if $_->{contest} && time >= $_->{rs}->contest->start; + } if $env->{'gruntmaster.contest'} && time >= db($env)->contest($env->{'gruntmaster.contest'})->start; }; }; @@ -145,7 +150,7 @@ thing { }; thing { - params qw/log Job/, 'Job log'; + params qw/log Job/, 'Job log', 'Job '; prefetch 'owner', 'problem'; makers { my $env = $_[0]; diff --git a/lib/Gruntmaster/Page/Submit.pm b/lib/Gruntmaster/Page/Submit.pm index 5eed07c..0c42de9 100644 --- a/lib/Gruntmaster/Page/Submit.pm +++ b/lib/Gruntmaster/Page/Submit.pm @@ -16,6 +16,8 @@ sub generate{ my ($self, $frm, $env) = @_; my $r = Plack::Request->new($env); my ($problem, $format, $contest, $private, $prog) = map {scalar $r->param($_)} 'problem', 'prog_format', 'contest', 'private', 'source_code'; + $problem //= $env->{'gruntmaster.problem'}; + $contest //= $env->{'gruntmaster.contest'}; my $upload = $r->upload('prog'); if (defined $upload) { my $temp = read_file $upload->path; @@ -26,7 +28,7 @@ sub generate{ return reply 'A required parameter was not supplied' if grep { !defined } $problem, $format, $prog; return reply 'Maximum source size is 10KB' if length $prog > 25 * 1024; return reply 'You must wait 30 seconds between jobs' unless time > db($env)->user($r->user)->lastjob + 30; - db($env)->user($r->user)->lastjob(time)->update; + db($env)->user($r->user)->update({lastjob => time}); db($env)->jobs->create({ defined $contest ? (contest => $contest) : (), @@ -34,14 +36,14 @@ sub generate{ extension => FORMAT_EXTENSION->{$format}, format => $format, defined $private ? (private => $private) : (), - probem => $problem, + problem => $problem, source => $prog, - user => $r->user + owner => $r->user }); $contest //= ''; #PUBLISH 'jobs', "$contest.$job"; - [303, [Location => $r->path =~ s,/pb/\w+/submit$,/log/,r], ['']] + [303, [Location => ($contest ? "/ct/$contest/log/" : '/log/')], ['']] } 1 diff --git a/lib/Plack/App/Gruntmaster.pm b/lib/Plack/App/Gruntmaster.pm index 8d828c0..e009d79 100644 --- a/lib/Plack/App/Gruntmaster.pm +++ b/lib/Plack/App/Gruntmaster.pm @@ -79,7 +79,7 @@ BEGIN{ generic qw/us ct pb log/; get qr,/log/src/$number\.$word, => 'Src'; - post qr,/pb/$word/submit, => 'Submit'; + post qr,/submit, => 'Submit'; post qr,/action/register, => 'Register'; post qr,/action/passwd, => 'Passwd'; diff --git a/tmpl/log.en b/tmpl/log.en index 1e5b488..f2c7983 100644 --- a/tmpl/log.en +++ b/tmpl/log.en @@ -12,6 +12,6 @@
    -
diff --git a/tmpl/pb.en b/tmpl/pb.en index fcb23b0..35cfbd4 100644 --- a/tmpl/pb.en +++ b/tmpl/pb.en @@ -3,7 +3,7 @@ -
NameAuthorOwner
+
@@ -13,7 +13,7 @@ -
NameAuthorOwner
+
@@ -23,7 +23,7 @@ -
NameAuthorOwner
+
@@ -33,7 +33,7 @@ -
NameAuthorOwner
+
diff --git a/tmpl/pb_entry.en b/tmpl/pb_entry.en index c707952..f3d0f75 100644 --- a/tmpl/pb_entry.en +++ b/tmpl/pb_entry.en @@ -13,7 +13,7 @@

Submit solution

-
+