Merge branch 'nodbic' into newmc-nodbic newmc-nodbic
authorMarius Gavrilescu <marius@ieval.ro>
Mon, 28 Sep 2015 10:24:03 +0000 (13:24 +0300)
committerMarius Gavrilescu <marius@ieval.ro>
Mon, 28 Sep 2015 10:24:03 +0000 (13:24 +0300)
1  2 
Makefile.PL
app.psgi
lib/Plack/App/Gruntmaster/HTML.pm
tmpl/pb_entry.en

diff --combined Makefile.PL
index a1698a17c2b3b70366fc737fd16f8e10a86a4689,2584deb709b1f8c26b14fd9148c12931ae38026f..d83230927ebff8d03c23bdb53d2c66ab45b65932
@@@ -10,13 -10,11 +10,12 @@@ WriteMakefile
        LICENSE           => 'AGPL_3',
        SIGN              => 1,
        clean             => {
 -              FILES => 'static/css/ static/js/'
 +              FILES => 'static/css/ static/js/ static/logos/'
        },
        BUILD_REQUIRES    => {
                qw/CSS::Minifier::XS          0
 +                 SVG::SpriteMaker           0
                   File::Slurp                0
-                  Test::MockTime             0
                   Test::More                 0
                   Test::WWW::Mechanize::PSGI 0/,
        },
@@@ -43,6 -41,7 +42,7 @@@
                   Plack::Middleware::Auth::Complex 0
                   Plack::Util                      0
                   Scope::Upper                     0
+                  Sort::ByExample                  0
                   Web::Simple                      0.019/,
        },
        META_MERGE        => {
diff --combined app.psgi
index 837dd60ab51e100408d84934eb6d7fd80a4a724c,a6125407f259fff9c545d8c1e92bdc79596e9cdb..20c8cb56f57a73f3c17f44ce03535e6aff9267bb
+++ b/app.psgi
@@@ -14,7 -14,7 +14,7 @@@ default-src 'none
  connect-src 'self'
  form-action 'self'
  frame-ancestors 'none'
 -img-src 'self'
 +img-src 'self' https://static.mindcoding.ro
  referrer origin-when-cross-origin
  script-src 'self'
  style-src 'self'
@@@ -23,15 -23,11 +23,11 @@@ CS
        $csp =~ s/\n/; /gr;
  }
  
- my $db;
  sub add_database {
        my $app = $_[0];
        sub {
-               my ($env) = @_;
-               $db //= Gruntmaster::Data->connect($ENV{GRUNTMASTER_DSN} // 'dbi:Pg:');
-               $env->{'gruntmaster.dbic'} = $db;
-               $app->($env)
+               dbinit $ENV{GRUNTMASTER_DSN} // 'dbi:Pg:' unless db;
+               $app->(@_)
        }
  }
  
index 6799fb107af2e2608a753798e64c1b7fd48b382b,c629383e76b9425eeaaff1a2947fcfa5b076f2ee..80ecac4c9f627c25f628472c23750ac0fea01490
@@@ -8,13 -8,16 +8,16 @@@ use HTML::Element::Library
  use HTML::TreeBuilder;
  use POSIX qw//;
  use Data::Dumper qw/Dumper/;
+ use Sort::ByExample
+   sorter => {-as => 'pb_sort', example => [qw/beginner easy medium hard/], xform => sub {$_->{level}}},
+   sorter => {-as => 'ct_sort', example => [qw/Running Pending Finished/], xform => sub {$_->{status}}};
  
  my $optional_end_tags = {%HTML::Tagset::optionalEndTag, tr => 1, td => 1, th => 1};
  
  sub ftime ($)   { POSIX::strftime '%c', localtime shift }
  sub literal ($) {
        my ($html) = @_;
-       return unless $html;
+       return '' unless $html;
        my $b = HTML::TreeBuilder->new;
        $b->ignore_unknown(0);
        $b->parse($html);
@@@ -46,7 -49,7 +49,7 @@@ sub HTML::Element::fclass { shift->look
  
  sub HTML::Element::namedlink {
        my ($self, $id, $name) = @_;
-       $name = $id unless $name =~ /[[:graph:]]/;
+       $name = $id unless $name && $name =~ /[[:graph:]]/;
        $self = $self->find('a');
        $self->edit_href(sub {s/id/$id/});
        $self->replace_content($name);
@@@ -161,7 -164,8 +164,8 @@@ sub process_ct 
                $tr->fclass('name')->namedlink($data->{id}, $data->{name});
                $tr->fclass('owner')->namedlink($data->{owner}, $data->{owner_name});
        };
-       $args{$_} ? $tree->fid($_)->find('tbody')->find('tr')->iter3($args{$_}, $iter) : $tree->fid($_)->detach for qw/running pending finished/;
+       $_->{status} = $_->{finished} ? 'Finished' : $_->{started} ? 'Running' : 'Pending' for @{$args{ct}};
+       $tree->find('tbody')->find('tr')->iter3([ct_sort @{$args{ct}}], $iter);
  }
  
  sub process_pb_entry {
        if ($args{contest_stop}) {
                $tree->fid('solution')->detach;
                $tree->fid('solution_modal')->detach;
 -              my $score = $tree->fid('score');
 -              $score->attr('data-start' => $args{open_time});
 -              $score->attr('data-stop'  => $args{contest_stop});
 -              $score->attr('data-value'  => $args{value});
 +              $tree->fid('score')->replace_content($args{value});
                $tree->fid('countdown')->attr('data-stop' => $args{contest_stop});
        } else {
                $tree->fid('job_log')->edit_href(sub{$_ .= "&private=$args{private}"}) if $args{private};
                $_->detach for $tree->fclass('rc'); # requires contest
                $tree->fid('solution_modal')->replace_content(literal $args{solution});
        }
-       if ($args{cansubmit}) {
-               $tree->fid('nosubmit')->detach;
-               $tree->look_down(name => 'problem')->attr(value => $args{id});
-               my $contest = $tree->look_down(name => 'contest');
-               $contest->attr(value => $args{args}{contest}) if $args{args}{contest};
-               $contest->detach unless $args{args}{contest}
-       } else {
-               $tree->fid('nosubmit')->find('a')->edit_href(sub{s/id/$args{id}/});
-               $tree->fid('submit')->detach
-       }
+       $tree->look_down(name => 'problem')->attr(value => $args{id});
+       my $contest = $tree->look_down(name => 'contest');
+       $contest->attr(value => $args{args}{contest}) if $args{args}{contest};
+       $contest->detach unless $args{args}{contest}
  }
  
  sub process_sol {
  
  sub process_pb {
        my ($tree, %args) = @_;
-       my $titer = sub {
+       my $iter = sub {
                my ($data, $tr) = @_;
                $tr->set_child_content(class => 'author', $data->{author});
+               $tr->set_child_content(class => 'level', ucfirst $data->{level});
                $tr->fclass('name')->namedlink($data->{id}, $data->{name});
                $tr->fclass('name')->find('a')->edit_href(sub {$_ .= "?contest=$args{contest}"}) if $args{contest};
                $tr->fclass('owner')->namedlink($data->{owner}, $data->{owner_name});
                $tr->find('td')->attr(class => $tr->find('td')->attr('class').' warning') if $data->{private} && !$args{contest};
        };
-       my $iter = sub {
-               my ($data, $div) = @_;
-               $div->attr(id => $data);
-               $div->find('h2')->replace_content(ucfirst $data);
-               $div->find('tbody')->find('tr')->iter3($args{$data}, $titer);
-       };
-       $tree->fid('beginner')->iter3([grep {$args{$_}} qw/beginner easy medium hard/], $iter);
+       $tree->find('tbody')->find('tr')->iter3([pb_sort @{$args{pb}}], $iter);
        $tree->fid('open-alert')->detach unless $args{contest};
  }
  
@@@ -312,7 -310,7 +307,7 @@@ sub process_ed 
                $div->set_child_content(class => 'solution', literal $data->{solution});
                $div->fclass('problem')->namedlink($data->{id}, $data->{name});
        };
-       my @pb = map { @{$args{$_} // []} } qw/beginner easy medium hard/;
+       my @pb = sort { $a->{value} <=> $b->{value} } @{$args{pb}};
        $tree->fclass('well')->iter3(\@pb, $iter);
  }
  
diff --combined tmpl/pb_entry.en
index 7f04fafe8a21e0b3933a67bb0b9f8bad9102dc20,f2709e321eb83bb1424dfe511063dc39eb1d5842..0732636929a70b9b5a03fcd650d68423a28dfa81
@@@ -6,7 -6,7 +6,7 @@@
  <dt>Owner</dt> <dd id="owner">owner</dd>
  <dt>Level</dt> <dd id="level">Easy</dd>
  <dt>Time limit (seconds)</dt> <dd smap="timeout">1</dd>
 -<dt class="rc reqjs">Score</dt> <dd id="score" class="timer reqjs rc" data-start="..." data-stop="..." data-value="100">50</dd>
 +<dt class="rc reqjs">Score</dt> <dd id="score" class="rc">50</dd>
  <dt class="rc reqjs">Contest ends in</dt> <dd id="countdown" class="timer reqjs rc" data-stop="...">01:30</dd>
  </dl>
  
  
  <h1>Submit solution</h1>
  
- <div id="nosubmit">
- The contest has finished.<br>
- To submit solutions to this problem, please visit the problem <a href="/pb/id">outside&nbsp;the&nbsp;contest</a>.
- </div>
  <div id="submit">
  <form id="submitform" action="/action/submit" method="POST" enctype="multipart/form-data" role="form">
  <input type="hidden" name="problem" value="problem_id">
  <div class="form-group"><label for="prog">File:</label><input id="prog" name="prog" type="file"></div>
  <div class="form-group"><label for="source_code">Source code:</label> <textarea class="form-control" id="source_code" name="source_code"></textarea></div>
  <div class="form-group"><label for="prog_format">File format:</label><select id="prog_format" name="prog_format" class="form-control" required>
 -<option value="C">C (gcc)</option>
 -<option value="CPP" selected>C++ (g++)</option>
 -<option value="GCCGO">Go (gccgo)</option>
 -<option value="GOLANG">Go (gc)</option>
 -<option value="GOLFSCRIPT">Golfscript (golfscript.rb)</option>
 -<option value="HASKELL">Haskell (ghc)</option>
 -<option value="JAVA">Java (javac)</option>
 -<option value="PASCAL">Pascal (fpc)</option>
 -<option value="PERL">Perl (perl)</option>
 -<option value="PYTHON">Python (python)</option>
 -<option value="RUBY">Ruby (ruby)</option>
 -<option value="SBCL">Common Lisp (sbcl)</option>
 +<option value="C">C11 (gcc 4.9.2)</option>
 +<option value="CPP" selected>C++11 (g++ 4.9.2)</option>
 +<option value="GCCGO">Go (gccgo 4.9.2)</option>
 +<option value="GOLANG">Go (gc 1.3.3)</option>
 +<!-- <option value="GOLFSCRIPT">Golfscript (golfscript.rb)</option> -->
 +<option value="HASKELL">Haskell (ghc 7.6.3)</option>
 +<option value="JAVA">Java (openjdk 7u75)</option>
 +<option value="PASCAL">Pascal (fpc 2.6.4)</option>
 +<option value="PERL">Perl (perl 5.20.2)</option>
 +<option value="PYTHON">Python (python 2.7.9)</option>
 +<option value="RUBY">Ruby (ruby 2.1.5)</option>
 +<option value="SBCL">Common Lisp (sbcl 1.2.4)</option>
  </select></div>
  
  <input type="submit" value="Submit job" class="btn btn-primary">
This page took 0.019928 seconds and 4 git commands to generate.