Description:
merge
Commit status:
[Not Reviewed]
References:
Diff options:
Comments:
0 Commit comments
0 Inline Comments
Unresolved TODOs:
There are no unresolved TODOs
r701:f26733606a76 - - 21 files changed: 104 inserted, 29 deleted
@@ -94,13 +94,13 | |||||
|
94 | flash[:notice] = 'Error adding your submission to task queue' |
|
94 | flash[:notice] = 'Error adding your submission to task queue' |
|
95 | end |
|
95 | end |
|
96 | else |
|
96 | else |
|
97 | prepare_list_information |
|
97 | prepare_list_information |
|
98 | render :action => 'list' and return |
|
98 | render :action => 'list' and return |
|
99 | end |
|
99 | end |
|
100 | - redirect_to :action => 'list' |
|
100 | + redirect_to edit_submission_path(@submission) |
|
101 | end |
|
101 | end |
|
102 |
|
102 | ||
|
103 | def source |
|
103 | def source |
|
104 | submission = Submission.find(params[:id]) |
|
104 | submission = Submission.find(params[:id]) |
|
105 | if ((submission.user_id == session[:user_id]) and |
|
105 | if ((submission.user_id == session[:user_id]) and |
|
106 | (submission.problem != nil) and |
|
106 | (submission.problem != nil) and |
@@ -162,13 +162,13 | |||||
|
162 | def stat |
|
162 | def stat |
|
163 | @problem = Problem.find(params[:id]) |
|
163 | @problem = Problem.find(params[:id]) |
|
164 | unless @problem.available or session[:admin] |
|
164 | unless @problem.available or session[:admin] |
|
165 | redirect_to :controller => 'main', :action => 'list' |
|
165 | redirect_to :controller => 'main', :action => 'list' |
|
166 | return |
|
166 | return |
|
167 | end |
|
167 | end |
|
168 | - @submissions = Submission.includes(:user).where(problem_id: params[:id]).order(:user_id,:id) |
|
168 | + @submissions = Submission.includes(:user).includes(:language).where(problem_id: params[:id]).order(:user_id,:id) |
|
169 |
|
169 | ||
|
170 | #stat summary |
|
170 | #stat summary |
|
171 | range =65 |
|
171 | range =65 |
|
172 | @histogram = { data: Array.new(range,0), summary: {} } |
|
172 | @histogram = { data: Array.new(range,0), summary: {} } |
|
173 | user = Hash.new(0) |
|
173 | user = Hash.new(0) |
|
174 | @submissions.find_each do |sub| |
|
174 | @submissions.find_each do |sub| |
@@ -206,12 +206,16 | |||||
|
206 | rescue => e |
|
206 | rescue => e |
|
207 | failed << p.full_name |
|
207 | failed << p.full_name |
|
208 | end |
|
208 | end |
|
209 | end |
|
209 | end |
|
210 | flash[:success] = "The following problems are added to the group #{group.name}: " + ok.join(', ') if ok.count > 0 |
|
210 | flash[:success] = "The following problems are added to the group #{group.name}: " + ok.join(', ') if ok.count > 0 |
|
211 | flash[:alert] = "The following problems are already in the group #{group.name}: " + failed.join(', ') if failed.count > 0 |
|
211 | flash[:alert] = "The following problems are already in the group #{group.name}: " + failed.join(', ') if failed.count > 0 |
|
|
212 | + elsif params.has_key? 'add_tags' | ||
|
|
213 | + get_problems_from_params.each do |p| | ||
|
|
214 | + p.tag_ids += params[:tag_ids] | ||
|
|
215 | + end | ||
|
212 | end |
|
216 | end |
|
213 |
|
217 | ||
|
214 | redirect_to :action => 'manage' |
|
218 | redirect_to :action => 'manage' |
|
215 | end |
|
219 | end |
|
216 |
|
220 | ||
|
217 | def import |
|
221 | def import |
@@ -297,10 +301,10 | |||||
|
297 | def get_problems_stat |
|
301 | def get_problems_stat |
|
298 | end |
|
302 | end |
|
299 |
|
303 | ||
|
300 | private |
|
304 | private |
|
301 |
|
305 | ||
|
302 | def problem_params |
|
306 | def problem_params |
|
303 | - params.require(:problem).permit(:name, :full_name, :full_score, :date_added, :available, :test_allowed,:output_only, :url, :description) |
|
307 | + params.require(:problem).permit(:name, :full_name, :full_score, :date_added, :available, :test_allowed,:output_only, :url, :description, tag_ids:[]) |
|
304 | end |
|
308 | end |
|
305 |
|
309 | ||
|
306 | end |
|
310 | end |
@@ -49,12 +49,14 | |||||
|
49 | User.includes(:contests).includes(:contest_stat).where(enabled: true) |
|
49 | User.includes(:contests).includes(:contest_stat).where(enabled: true) |
|
50 | end |
|
50 | end |
|
51 |
|
51 | ||
|
52 | #set up range from param |
|
52 | #set up range from param |
|
53 | @since_id = params.fetch(:from_id, 0).to_i |
|
53 | @since_id = params.fetch(:from_id, 0).to_i |
|
54 | @until_id = params.fetch(:to_id, 0).to_i |
|
54 | @until_id = params.fetch(:to_id, 0).to_i |
|
|
55 | + @since_id = nil if @since_id == 0 | ||
|
|
56 | + @until_id = nil if @until_id == 0 | ||
|
55 |
|
57 | ||
|
56 | #calculate the routine |
|
58 | #calculate the routine |
|
57 | @scorearray = calculate_max_score(@problems, @users, @since_id, @until_id) |
|
59 | @scorearray = calculate_max_score(@problems, @users, @since_id, @until_id) |
|
58 |
|
60 | ||
|
59 | #rencer accordingly |
|
61 | #rencer accordingly |
|
60 | if params[:button] == 'download' then |
|
62 | if params[:button] == 'download' then |
@@ -38,12 +38,14 | |||||
|
38 | render :edit |
|
38 | render :edit |
|
39 | end |
|
39 | end |
|
40 | end |
|
40 | end |
|
41 |
|
41 | ||
|
42 | # DELETE /tags/1 |
|
42 | # DELETE /tags/1 |
|
43 | def destroy |
|
43 | def destroy |
|
|
44 | + #remove any association | ||
|
|
45 | + ProblemTag.where(tag_id: @tag.id).destroy_all | ||
|
44 | @tag.destroy |
|
46 | @tag.destroy |
|
45 | redirect_to tags_url, notice: 'Tag was successfully destroyed.' |
|
47 | redirect_to tags_url, notice: 'Tag was successfully destroyed.' |
|
46 | end |
|
48 | end |
|
47 |
|
49 | ||
|
48 | private |
|
50 | private |
|
49 | # Use callbacks to share common setup or constraints between actions. |
|
51 | # Use callbacks to share common setup or constraints between actions. |
@@ -82,27 +82,30 | |||||
|
82 | option << link_to_unless_current(label, |
|
82 | option << link_to_unless_current(label, |
|
83 | :controller => controller, |
|
83 | :controller => controller, |
|
84 | :action => action) |
|
84 | :action => action) |
|
85 | end |
|
85 | end |
|
86 |
|
86 | ||
|
87 | def format_short_time(time) |
|
87 | def format_short_time(time) |
|
88 |
- now = Time.now |
|
88 | + now = Time.zone.now |
|
89 | st = '' |
|
89 | st = '' |
|
90 | - if (time.yday != now.yday) or |
|
90 | + if (time.yday != now.yday) or (time.year != now.year) |
|
91 | - (time.year != now.year) |
|
91 | + st = time.strftime("%d/%m/%y ") |
|
92 | - st = time.strftime("%x ") |
|
||
|
93 | end |
|
92 | end |
|
94 | st + time.strftime("%X") |
|
93 | st + time.strftime("%X") |
|
95 | end |
|
94 | end |
|
96 |
|
95 | ||
|
97 | def format_short_duration(duration) |
|
96 | def format_short_duration(duration) |
|
98 | return '' if duration==nil |
|
97 | return '' if duration==nil |
|
99 | d = duration.to_f |
|
98 | d = duration.to_f |
|
100 | return Time.at(d).gmtime.strftime("%X") |
|
99 | return Time.at(d).gmtime.strftime("%X") |
|
101 | end |
|
100 | end |
|
102 |
|
101 | ||
|
|
102 | + def format_full_time_ago(time) | ||
|
|
103 | + st = time_ago_in_words(time) + ' ago (' + format_short_time(time) + ')' | ||
|
|
104 | + end | ||
|
|
105 | + | ||
|
103 | def read_textfile(fname,max_size=2048) |
|
106 | def read_textfile(fname,max_size=2048) |
|
104 | begin |
|
107 | begin |
|
105 | File.open(fname).read(max_size) |
|
108 | File.open(fname).read(max_size) |
|
106 | rescue |
|
109 | rescue |
|
107 | nil |
|
110 | nil |
|
108 | end |
|
111 | end |
@@ -31,14 +31,14 | |||||
|
31 | "GROUP BY user_id) " + |
|
31 | "GROUP BY user_id) " + |
|
32 | "ORDER BY user_id") |
|
32 | "ORDER BY user_id") |
|
33 | end |
|
33 | end |
|
34 |
|
34 | ||
|
35 | def self.find_in_range_by_user_and_problem(user_id, problem_id,since_id,until_id) |
|
35 | def self.find_in_range_by_user_and_problem(user_id, problem_id,since_id,until_id) |
|
36 | records = Submission.where(problem_id: problem_id,user_id: user_id) |
|
36 | records = Submission.where(problem_id: problem_id,user_id: user_id) |
|
37 | - records = records.where('id >= ?',since_id) if since_id > 0 |
|
37 | + records = records.where('id >= ?',since_id) if since_id and since_id > 0 |
|
38 | - records = records.where('id <= ?',until_id) if until_id > 0 |
|
38 | + records = records.where('id <= ?',until_id) if until_id and until_id > 0 |
|
39 | records.all |
|
39 | records.all |
|
40 | end |
|
40 | end |
|
41 |
|
41 | ||
|
42 | def self.find_last_for_all_available_problems(user_id) |
|
42 | def self.find_last_for_all_available_problems(user_id) |
|
43 | submissions = Array.new |
|
43 | submissions = Array.new |
|
44 | problems = Problem.available_problems |
|
44 | problems = Problem.available_problems |
@@ -1,26 +1,28 | |||||
|
1 | - |
|
||
|
2 |
|
|
1 | - if submission.nil? |
|
3 | = "-" |
|
2 | = "-" |
|
4 | - else |
|
3 | - else |
|
|
4 | + %strong= "Submission ID:" | ||
|
|
5 | + = submission.id | ||
|
|
6 | + %br | ||
|
5 | - unless submission.graded_at |
|
7 | - unless submission.graded_at |
|
6 | - = t 'main.submitted_at' |
|
8 | + %strong= t 'main.submitted_at:' |
|
7 |
- = format_ |
|
9 | + = format_full_time_ago(submission.submitted_at.localtime) |
|
8 | - else |
|
10 | - else |
|
9 | - %strong= t 'main.graded_at' |
|
11 | + %strong= t 'main.graded_at:' |
|
10 |
- = |
|
12 | + = format_full_time_ago(submission.graded_at.localtime) |
|
11 | %br |
|
13 | %br |
|
12 | - if GraderConfiguration['ui.show_score'] |
|
14 | - if GraderConfiguration['ui.show_score'] |
|
13 | %strong=t 'main.score' |
|
15 | %strong=t 'main.score' |
|
14 | = "#{(submission.points*100/submission.problem.full_score).to_i} " |
|
16 | = "#{(submission.points*100/submission.problem.full_score).to_i} " |
|
15 | = " [" |
|
17 | = " [" |
|
16 | %tt |
|
18 | %tt |
|
17 | = submission.grader_comment |
|
19 | = submission.grader_comment |
|
18 | = "]" |
|
20 | = "]" |
|
19 | %br |
|
21 | %br |
|
20 |
|
|
22 | %strong View: |
|
21 |
|
|
23 | - if GraderConfiguration.show_grading_result |
|
22 |
|
|
24 | = link_to '[detailed result]', :action => 'result', :id => submission.id |
|
23 |
- |
|
25 | + = link_to "#{t 'main.cmp_msg'}", {:action => 'compiler_msg', :id => submission.id}, {popup: true,class: 'btn btn-xs btn-info'} if submission.graded_at |
|
24 | = link_to "#{t 'main.src_link'}", download_submission_path(submission.id), class: 'btn btn-xs btn-info' |
|
26 | = link_to "#{t 'main.src_link'}", download_submission_path(submission.id), class: 'btn btn-xs btn-info' |
|
25 | = link_to "#{t 'main.submissions_link'}", problem_submissions_path(problem_id), class: 'btn btn-xs btn-info' |
|
27 | = link_to "#{t 'main.submissions_link'}", problem_submissions_path(problem_id), class: 'btn btn-xs btn-info' |
|
26 |
|
28 |
@@ -43,12 +43,13 | |||||
|
43 | %a.dropdown-toggle{href: '#', data: {toggle:'dropdown'}, aria: {haspopup:"true", expanded:"false"}, role: "button"} |
|
43 | %a.dropdown-toggle{href: '#', data: {toggle:'dropdown'}, aria: {haspopup:"true", expanded:"false"}, role: "button"} |
|
44 | Manage |
|
44 | Manage |
|
45 | %span.caret |
|
45 | %span.caret |
|
46 | %ul.dropdown-menu |
|
46 | %ul.dropdown-menu |
|
47 | = add_menu( 'Announcements', 'announcements', 'index') |
|
47 | = add_menu( 'Announcements', 'announcements', 'index') |
|
48 | = add_menu( 'Problems', 'problems', 'index') |
|
48 | = add_menu( 'Problems', 'problems', 'index') |
|
|
49 | + = add_menu( 'Tags', 'tags', 'index') | ||
|
49 | = add_menu( 'Users', 'user_admin', 'index') |
|
50 | = add_menu( 'Users', 'user_admin', 'index') |
|
50 | = add_menu( 'User Groups', 'groups', 'index') |
|
51 | = add_menu( 'User Groups', 'groups', 'index') |
|
51 | = add_menu( 'Graders', 'graders', 'list') |
|
52 | = add_menu( 'Graders', 'graders', 'list') |
|
52 | = add_menu( 'Message ', 'messages', 'console') |
|
53 | = add_menu( 'Message ', 'messages', 'console') |
|
53 | %li.divider{role: 'separator'} |
|
54 | %li.divider{role: 'separator'} |
|
54 | = add_menu( 'System config', 'configurations', 'index') |
|
55 | = add_menu( 'System config', 'configurations', 'index') |
@@ -9,12 +9,15 | |||||
|
9 | %label{:for => "problem_full_name"} Full name |
|
9 | %label{:for => "problem_full_name"} Full name |
|
10 | = text_field 'problem', 'full_name', class: 'form-control' |
|
10 | = text_field 'problem', 'full_name', class: 'form-control' |
|
11 | .form-group |
|
11 | .form-group |
|
12 | %label{:for => "problem_full_score"} Full score |
|
12 | %label{:for => "problem_full_score"} Full score |
|
13 | = text_field 'problem', 'full_score', class: 'form-control' |
|
13 | = text_field 'problem', 'full_score', class: 'form-control' |
|
14 | .form-group |
|
14 | .form-group |
|
|
15 | + %label{:for => "problem_full_score"} Tags | ||
|
|
16 | + = collection_select(:problem, :tag_ids, Tag.all, :id, :name, {}, {multiple: true, class: 'form-control select2'}) | ||
|
|
17 | + .form-group | ||
|
15 | %label{:for => "problem_date_added"} Date added |
|
18 | %label{:for => "problem_date_added"} Date added |
|
16 | = date_select 'problem', 'date_added', class: 'form-control' |
|
19 | = date_select 'problem', 'date_added', class: 'form-control' |
|
17 | - # TODO: these should be put in model Problem, but I can't think of |
|
20 | - # TODO: these should be put in model Problem, but I can't think of |
|
18 | - # nice default values for them. These values look fine only |
|
21 | - # nice default values for them. These values look fine only |
|
19 | - # in this case (of lazily adding new problems). |
|
22 | - # in this case (of lazily adding new problems). |
|
20 | - @problem.available = true if @problem!=nil and @problem.available==nil |
|
23 | - @problem.available = true if @problem!=nil and @problem.available==nil |
@@ -18,12 +18,13 | |||||
|
18 | = submit_tag "Create" |
|
18 | = submit_tag "Create" |
|
19 | %table.table.table-condense.table-hover |
|
19 | %table.table.table-condense.table-hover |
|
20 | %thead |
|
20 | %thead |
|
21 | %th Name |
|
21 | %th Name |
|
22 | %th Full name |
|
22 | %th Full name |
|
23 | %th.text-right Full score |
|
23 | %th.text-right Full score |
|
|
24 | + %th Tags | ||
|
24 | %th |
|
25 | %th |
|
25 | Submit |
|
26 | Submit |
|
26 | %sup{class: 'text-primary',data: {toggle: 'tooltip'}, title: 'Admin can always submit to any problem' } [?] |
|
27 | %sup{class: 'text-primary',data: {toggle: 'tooltip'}, title: 'Admin can always submit to any problem' } [?] |
|
27 | %th Date added |
|
28 | %th Date added |
|
28 | %th.text-center |
|
29 | %th.text-center |
|
29 | Avail? |
|
30 | Avail? |
@@ -41,12 +42,16 | |||||
|
41 | - @problem=problem |
|
42 | - @problem=problem |
|
42 | %td= problem.name #in_place_editor_field :problem, :name, {}, :rows=>1 |
|
43 | %td= problem.name #in_place_editor_field :problem, :name, {}, :rows=>1 |
|
43 | %td |
|
44 | %td |
|
44 | = problem.full_name #in_place_editor_field :problem, :full_name, {}, :rows=>1 |
|
45 | = problem.full_name #in_place_editor_field :problem, :full_name, {}, :rows=>1 |
|
45 | = link_to_description_if_any "[#{t 'main.problem_desc'}] <span class='glyphicon glyphicon-file'></span>".html_safe, problem |
|
46 | = link_to_description_if_any "[#{t 'main.problem_desc'}] <span class='glyphicon glyphicon-file'></span>".html_safe, problem |
|
46 | %td.text-right= problem.full_score #in_place_editor_field :problem, :full_score, {}, :rows=>1 |
|
47 | %td.text-right= problem.full_score #in_place_editor_field :problem, :full_score, {}, :rows=>1 |
|
|
48 | + %td | ||
|
|
49 | + - problem.tags.each do |t| | ||
|
|
50 | + - #%button.btn.btn-default.btn-xs= t.name | ||
|
|
51 | + %span.label.label-default= t.name | ||
|
47 | %td= link_to "Submit", direct_edit_problem_submissions_path(problem,@current_user.id), class: 'btn btn-xs btn-primary' |
|
52 | %td= link_to "Submit", direct_edit_problem_submissions_path(problem,@current_user.id), class: 'btn btn-xs btn-primary' |
|
48 | %td= problem.date_added |
|
53 | %td= problem.date_added |
|
49 | %td= toggle_button(@problem.available?, toggle_problem_path(@problem), "problem-avail-#{@problem.id}") |
|
54 | %td= toggle_button(@problem.available?, toggle_problem_path(@problem), "problem-avail-#{@problem.id}") |
|
50 | %td= toggle_button(@problem.view_testcase?, toggle_view_testcase_problem_path(@problem), "problem-view-testcase-#{@problem.id}") |
|
55 | %td= toggle_button(@problem.view_testcase?, toggle_view_testcase_problem_path(@problem), "problem-view-testcase-#{@problem.id}") |
|
51 | %td= toggle_button(@problem.test_allowed?, toggle_test_problem_path(@problem), "problem-test-#{@problem.id}") |
|
56 | %td= toggle_button(@problem.test_allowed?, toggle_test_problem_path(@problem), "problem-test-#{@problem.id}") |
|
52 | - if GraderConfiguration.multicontests? |
|
57 | - if GraderConfiguration.multicontests? |
@@ -46,53 +46,62 | |||||
|
46 | .submit-box |
|
46 | .submit-box |
|
47 | What do you want to do to the selected problem? |
|
47 | What do you want to do to the selected problem? |
|
48 | %br/ |
|
48 | %br/ |
|
49 | (You can shift-click to select a range of problems) |
|
49 | (You can shift-click to select a range of problems) |
|
50 | %ul.form-inline |
|
50 | %ul.form-inline |
|
51 | %li |
|
51 | %li |
|
52 |
- Change |
|
52 | + Change "Date added" to |
|
53 | .input-group.date |
|
53 | .input-group.date |
|
54 | = text_field_tag :date_added, class: 'form-control' |
|
54 | = text_field_tag :date_added, class: 'form-control' |
|
55 | %span.input-group-addon |
|
55 | %span.input-group-addon |
|
56 | %span.glyphicon.glyphicon-calendar |
|
56 | %span.glyphicon.glyphicon-calendar |
|
57 | -# = select_date Date.current, :prefix => 'date_added' |
|
57 | -# = select_date Date.current, :prefix => 'date_added' |
|
58 | |
|
58 | |
|
59 | = submit_tag 'Change', :name => 'change_date_added', class: 'btn btn-primary btn-sm' |
|
59 | = submit_tag 'Change', :name => 'change_date_added', class: 'btn btn-primary btn-sm' |
|
60 | %li |
|
60 | %li |
|
61 |
- Set |
|
61 | + Set "Available" to |
|
62 | = submit_tag 'True', :name => 'enable_problem', class: 'btn btn-primary btn-sm' |
|
62 | = submit_tag 'True', :name => 'enable_problem', class: 'btn btn-primary btn-sm' |
|
63 | = submit_tag 'False', :name => 'disable_problem', class: 'btn btn-primary btn-sm' |
|
63 | = submit_tag 'False', :name => 'disable_problem', class: 'btn btn-primary btn-sm' |
|
64 |
|
64 | ||
|
65 | - if GraderConfiguration.multicontests? |
|
65 | - if GraderConfiguration.multicontests? |
|
66 | %li |
|
66 | %li |
|
67 | - Add to |
|
67 | + Add selected problems to contest |
|
68 | = select("contest","id",Contest.all.collect {|c| [c.title, c.id]}) |
|
68 | = select("contest","id",Contest.all.collect {|c| [c.title, c.id]}) |
|
69 | = submit_tag 'Add', :name => 'add_to_contest', class: 'btn btn-primary btn-sm' |
|
69 | = submit_tag 'Add', :name => 'add_to_contest', class: 'btn btn-primary btn-sm' |
|
70 | %li |
|
70 | %li |
|
71 | - Add problems to group |
|
71 | + Add selected problems to user group |
|
72 | = select_tag "group_id", options_from_collection_for_select( Group.all, 'id','name',params[:group_name]), id: 'group_name',class: 'select2' |
|
72 | = select_tag "group_id", options_from_collection_for_select( Group.all, 'id','name',params[:group_name]), id: 'group_name',class: 'select2' |
|
73 |
- = submit_tag 'Add', name: 'add_group', class: 'btn btn- |
|
73 | + = submit_tag 'Add', name: 'add_group', class: 'btn btn-primary' |
|
|
74 | + %li | ||
|
|
75 | + Add the following tags to the selected problems | ||
|
|
76 | + = select_tag "tag_ids", options_from_collection_for_select( Tag.all, 'id','name'), id: 'tags_name',class: 'select2', multiple: true, data: {placeholder: 'Select tags by clicking', width: "200px"} | ||
|
|
77 | + = submit_tag 'Add', name: 'add_tags', class: 'btn btn-primary' | ||
|
74 |
|
78 | ||
|
75 | - |
|
79 | + %table.table.table-hover.datatable |
|
76 | - %table.table.table-hover |
|
80 | + %thead |
|
77 | %tr{style: "text-align: left;"} |
|
81 | %tr{style: "text-align: left;"} |
|
78 | %th= check_box_tag 'select_all' |
|
82 | %th= check_box_tag 'select_all' |
|
79 | %th Name |
|
83 | %th Name |
|
80 | %th Full name |
|
84 | %th Full name |
|
|
85 | + %th Tags | ||
|
81 | %th Available |
|
86 | %th Available |
|
82 | %th Date added |
|
87 | %th Date added |
|
83 | - if GraderConfiguration.multicontests? |
|
88 | - if GraderConfiguration.multicontests? |
|
84 | %th Contests |
|
89 | %th Contests |
|
85 |
|
90 | ||
|
|
91 | + %tbody | ||
|
86 | - num = 0 |
|
92 | - num = 0 |
|
87 | - for problem in @problems |
|
93 | - for problem in @problems |
|
88 | - num += 1 |
|
94 | - num += 1 |
|
89 | %tr{:id => "row-prob-#{problem.id}", :name=> "prob-#{problem.id}"} |
|
95 | %tr{:id => "row-prob-#{problem.id}", :name=> "prob-#{problem.id}"} |
|
90 | %td= check_box_tag "prob-#{problem.id}-#{num}" |
|
96 | %td= check_box_tag "prob-#{problem.id}-#{num}" |
|
91 | %td= problem.name |
|
97 | %td= problem.name |
|
92 | %td= problem.full_name |
|
98 | %td= problem.full_name |
|
|
99 | + %td | ||
|
|
100 | + - problem.tags.each do |t| | ||
|
|
101 | + %span.label.label-default= t.name | ||
|
93 | %td= problem.available |
|
102 | %td= problem.available |
|
94 | %td= problem.date_added |
|
103 | %td= problem.date_added |
|
95 | - if GraderConfiguration.multicontests? |
|
104 | - if GraderConfiguration.multicontests? |
|
96 | %td |
|
105 | %td |
|
97 | - problem.contests.each do |contest| |
|
106 | - problem.contests.each do |contest| |
|
98 | = "(#{contest.name} [#{link_to 'x', :action => 'remove_contest', :id => problem.id, :contest_id => contest.id }])" |
|
107 | = "(#{contest.name} [#{link_to 'x', :action => 'remove_contest', :id => problem.id, :contest_id => contest.id }])" |
@@ -101,7 +110,9 | |||||
|
101 | $('.input-group.date').datetimepicker({ |
|
110 | $('.input-group.date').datetimepicker({ |
|
102 | format: 'DD/MMM/YYYY', |
|
111 | format: 'DD/MMM/YYYY', |
|
103 | showTodayButton: true, |
|
112 | showTodayButton: true, |
|
104 | widgetPositioning: {horizontal: 'auto', vertical: 'bottom'}, |
|
113 | widgetPositioning: {horizontal: 'auto', vertical: 'bottom'}, |
|
105 |
|
114 | ||
|
106 | }); |
|
115 | }); |
|
107 | - |
|
116 | + $('.datatable').DataTable({ |
|
|
117 | + paging: false | ||
|
|
118 | + }); |
@@ -29,12 +29,13 | |||||
|
29 | %thead |
|
29 | %thead |
|
30 | %tr |
|
30 | %tr |
|
31 | %th ID |
|
31 | %th ID |
|
32 | %th Login |
|
32 | %th Login |
|
33 | %th Name |
|
33 | %th Name |
|
34 | %th Submitted_at |
|
34 | %th Submitted_at |
|
|
35 | + %th language | ||
|
35 | %th Points |
|
36 | %th Points |
|
36 | %th comment |
|
37 | %th comment |
|
37 | %th IP |
|
38 | %th IP |
|
38 | %tbody |
|
39 | %tbody |
|
39 | - row_odd,curr = true,'' |
|
40 | - row_odd,curr = true,'' |
|
40 | - @submissions.each do |sub| |
|
41 | - @submissions.each do |sub| |
@@ -42,12 +43,13 | |||||
|
42 | - row_odd,curr = !row_odd, sub.user if curr != sub.user |
|
43 | - row_odd,curr = !row_odd, sub.user if curr != sub.user |
|
43 | %tr |
|
44 | %tr |
|
44 | %td= link_to sub.id, submission_path(sub) |
|
45 | %td= link_to sub.id, submission_path(sub) |
|
45 | %td= link_to sub.user.login, stat_user_path(sub.user) |
|
46 | %td= link_to sub.user.login, stat_user_path(sub.user) |
|
46 | %td= sub.user.full_name |
|
47 | %td= sub.user.full_name |
|
47 | %td{data: {order: sub.submitted_at}}= time_ago_in_words(sub.submitted_at) + " ago" |
|
48 | %td{data: {order: sub.submitted_at}}= time_ago_in_words(sub.submitted_at) + " ago" |
|
|
49 | + %td= sub.language.name | ||
|
48 | %td= sub.points |
|
50 | %td= sub.points |
|
49 | %td.fix-width= sub.grader_comment |
|
51 | %td.fix-width= sub.grader_comment |
|
50 | %td= sub.ip_address |
|
52 | %td= sub.ip_address |
|
51 | - else |
|
53 | - else |
|
52 | No submission |
|
54 | No submission |
|
53 |
|
55 |
@@ -9,12 +9,15 | |||||
|
9 | %th Remark |
|
9 | %th Remark |
|
10 | - @problems.each do |p| |
|
10 | - @problems.each do |p| |
|
11 | %th.text-right= p.name.gsub('_',' ') |
|
11 | %th.text-right= p.name.gsub('_',' ') |
|
12 | %th.text-right Total |
|
12 | %th.text-right Total |
|
13 | %th.text-right Passed |
|
13 | %th.text-right Passed |
|
14 | %tbody |
|
14 | %tbody |
|
|
15 | + - sum = Array.new(@scorearray[0].count,0) | ||
|
|
16 | + - nonzero = Array.new(@scorearray[0].count,0) | ||
|
|
17 | + - full = Array.new(@scorearray[0].count,0) | ||
|
15 | - @scorearray.each do |sc| |
|
18 | - @scorearray.each do |sc| |
|
16 | %tr |
|
19 | %tr |
|
17 | - total,num_passed = 0,0 |
|
20 | - total,num_passed = 0,0 |
|
18 | - sc.each_index do |i| |
|
21 | - sc.each_index do |i| |
|
19 | - if i == 0 |
|
22 | - if i == 0 |
|
20 | %td= link_to sc[i].login, stat_user_path(sc[i]) |
|
23 | %td= link_to sc[i].login, stat_user_path(sc[i]) |
@@ -24,11 +27,43 | |||||
|
24 | / %td= sc[i].contests.collect {|c| c.name}.join(', ') |
|
27 | / %td= sc[i].contests.collect {|c| c.name}.join(', ') |
|
25 | %td= sc[i].remark |
|
28 | %td= sc[i].remark |
|
26 | - else |
|
29 | - else |
|
27 | %td.text-right= sc[i][0] |
|
30 | %td.text-right= sc[i][0] |
|
28 | - total += sc[i][0] |
|
31 | - total += sc[i][0] |
|
29 | - num_passed += 1 if sc[i][1] |
|
32 | - num_passed += 1 if sc[i][1] |
|
|
33 | + - sum[i] += sc[i][0] | ||
|
|
34 | + - nonzero[i] += 1 if sc[i][0] > 0 | ||
|
|
35 | + - full[i] += 1 if sc[i][1] | ||
|
30 | %td.text-right= total |
|
36 | %td.text-right= total |
|
31 | %td.text-right= num_passed |
|
37 | %td.text-right= num_passed |
|
|
38 | + %tfoot | ||
|
|
39 | + %tr | ||
|
|
40 | + %td Summation | ||
|
|
41 | + %td | ||
|
|
42 | + %td | ||
|
|
43 | + - sum.each.with_index do |s,i| | ||
|
|
44 | + - next if i == 0 | ||
|
|
45 | + %td.text-right= number_with_delimiter(s) | ||
|
|
46 | + %td | ||
|
|
47 | + %td | ||
|
|
48 | + %tr | ||
|
|
49 | + %td partial solver | ||
|
|
50 | + %td | ||
|
|
51 | + %td | ||
|
|
52 | + - nonzero.each.with_index do |s,i| | ||
|
|
53 | + - next if i == 0 | ||
|
|
54 | + %td.text-right= number_with_delimiter(s) | ||
|
|
55 | + %td | ||
|
|
56 | + %td | ||
|
|
57 | + %tr | ||
|
|
58 | + %td Full solver | ||
|
|
59 | + %td | ||
|
|
60 | + %td | ||
|
|
61 | + - full.each.with_index do |s,i| | ||
|
|
62 | + - next if i == 0 | ||
|
|
63 | + %td.text-right= number_with_delimiter(s) | ||
|
|
64 | + %td | ||
|
|
65 | + %td | ||
|
|
66 | + | ||
|
32 |
|
67 | ||
|
33 | :javascript |
|
68 | :javascript |
|
34 | $.bootstrapSortable(true,'reversed') |
|
69 | $.bootstrapSortable(true,'reversed') |
@@ -30,17 +30,17 | |||||
|
30 | .panel.panel-primary |
|
30 | .panel.panel-primary |
|
31 | .panel-heading |
|
31 | .panel-heading |
|
32 | Users |
|
32 | Users |
|
33 | .panel-body |
|
33 | .panel-body |
|
34 | .radio |
|
34 | .radio |
|
35 | %label |
|
35 | %label |
|
36 |
- = radio_button_tag 'users', 'all', |
|
36 | + = radio_button_tag 'users', 'all', (params[:users] == "all") |
|
37 | All users |
|
37 | All users |
|
38 | .radio |
|
38 | .radio |
|
39 | %label |
|
39 | %label |
|
40 | - = radio_button_tag 'users', 'enabled' |
|
40 | + = radio_button_tag 'users', 'enabled', (params[:users] == "enabled") |
|
41 | Only enabled users |
|
41 | Only enabled users |
|
42 | .row |
|
42 | .row |
|
43 | .col-md-12 |
|
43 | .col-md-12 |
|
44 | = button_tag 'Show', class: "btn btn-primary btn-large", value: "show" |
|
44 | = button_tag 'Show', class: "btn btn-primary btn-large", value: "show" |
|
45 | = button_tag 'Download CSV', class: "btn btn-primary btn-large", value: "download" |
|
45 | = button_tag 'Download CSV', class: "btn btn-primary btn-large", value: "download" |
|
46 |
|
46 |
@@ -28,8 +28,9 | |||||
|
28 | = link_to 'Back', sites_path |
|
28 | = link_to 'Back', sites_path |
|
29 |
|
29 | ||
|
30 |
|
30 | ||
|
31 | :javascript |
|
31 | :javascript |
|
32 | $('.input-group.date').datetimepicker({ |
|
32 | $('.input-group.date').datetimepicker({ |
|
33 | format: 'DD/MMM/YYYY HH:mm', |
|
33 | format: 'DD/MMM/YYYY HH:mm', |
|
|
34 | + showTodayButton: true, | ||
|
34 | }); |
|
35 | }); |
|
35 |
|
36 |
@@ -24,17 +24,18 | |||||
|
24 | = label_tag 'Language' |
|
24 | = label_tag 'Language' |
|
25 | = select_tag 'language_id', options_from_collection_for_select(Language.all, 'id', 'pretty_name', @lang_id || Language.find_by_pretty_name("Python").id || Language.first.id), class: 'form-control select', style: "width: 100px" |
|
25 | = select_tag 'language_id', options_from_collection_for_select(Language.all, 'id', 'pretty_name', @lang_id || Language.find_by_pretty_name("Python").id || Language.first.id), class: 'form-control select', style: "width: 100px" |
|
26 | .form-group |
|
26 | .form-group |
|
27 | = submit_tag 'Submit', class: 'btn btn-success', id: 'live_submit', |
|
27 | = submit_tag 'Submit', class: 'btn btn-success', id: 'live_submit', |
|
28 | data: {confirm: "Submitting this source code for task #{@problem.long_name}?"} |
|
28 | data: {confirm: "Submitting this source code for task #{@problem.long_name}?"} |
|
29 | - # latest submission status |
|
29 | - # latest submission status |
|
30 | - .panel.panel-info |
|
30 | + .panel{class: (@submission && @submission.graded_at) ? "panel-info" : "panel-warning"} |
|
31 | .panel-heading |
|
31 | .panel-heading |
|
32 | Latest Submission Status |
|
32 | Latest Submission Status |
|
33 | = link_to "Refresh",get_latest_submission_status_submissions_path(@submission.user,@problem), class: "btn btn-default btn-sm", remote: true if @submission |
|
33 | = link_to "Refresh",get_latest_submission_status_submissions_path(@submission.user,@problem), class: "btn btn-default btn-sm", remote: true if @submission |
|
34 | .panel-body |
|
34 | .panel-body |
|
|
35 | + %div#latest_status | ||
|
35 | - if @submission |
|
36 | - if @submission |
|
36 | = render :partial => 'submission_short', |
|
37 | = render :partial => 'submission_short', |
|
37 | :locals => {submission: @submission, problem_name: @problem.name, problem_id: @problem.id } |
|
38 | :locals => {submission: @submission, problem_name: @problem.name, problem_id: @problem.id } |
|
38 | .row |
|
39 | .row |
|
39 | .col-md-12 |
|
40 | .col-md-12 |
|
40 | %h2 Console |
|
41 | %h2 Console |
@@ -1,2 +1,2 | |||||
|
1 | :plain |
|
1 | :plain |
|
2 | - $("#latest_status").html("#{j render({partial: 'submission_short', locals: {submission: @submission, problem_name: @problem.name}})}") |
|
2 | + $("#latest_status").html("#{j render({partial: 'submission_short', locals: {submission: @submission, problem_name: @problem.name, problem_id: @problem.id}})}") |
@@ -62,11 +62,11 | |||||
|
62 | config.assets.paths << "#{Rails}/vendor/assets/fonts" |
|
62 | config.assets.paths << "#{Rails}/vendor/assets/fonts" |
|
63 |
|
63 | ||
|
64 | config.assets.precompile += ['announcement_refresh.js','effects.js','site_update.js'] |
|
64 | config.assets.precompile += ['announcement_refresh.js','effects.js','site_update.js'] |
|
65 | config.assets.precompile += ['local_jquery.js','tablesorter-theme.cafe.css'] |
|
65 | config.assets.precompile += ['local_jquery.js','tablesorter-theme.cafe.css'] |
|
66 | %w( announcements submissions configurations contests contest_management graders heartbeat |
|
66 | %w( announcements submissions configurations contests contest_management graders heartbeat |
|
67 | login main messages problems report site sites sources tasks |
|
67 | login main messages problems report site sites sources tasks |
|
68 | - test user_admin users ).each do |controller| |
|
68 | + test user_admin users testcases).each do |controller| |
|
69 | config.assets.precompile += ["#{controller}.js", "#{controller}.css"] |
|
69 | config.assets.precompile += ["#{controller}.js", "#{controller}.css"] |
|
70 | end |
|
70 | end |
|
71 | end |
|
71 | end |
|
72 | end |
|
72 | end |
@@ -15,9 +15,9 | |||||
|
15 | # Rails.application.config.assets.precompile += %w( admin.js admin.css ) |
|
15 | # Rails.application.config.assets.precompile += %w( admin.js admin.css ) |
|
16 |
|
16 | ||
|
17 | Rails.application.config.assets.precompile += ['announcement_refresh.js','effects.js','site_update.js'] |
|
17 | Rails.application.config.assets.precompile += ['announcement_refresh.js','effects.js','site_update.js'] |
|
18 | Rails.application.config.assets.precompile += ['local_jquery.js','tablesorter-theme.cafe.css'] |
|
18 | Rails.application.config.assets.precompile += ['local_jquery.js','tablesorter-theme.cafe.css'] |
|
19 | %w( announcements submissions configurations contests contest_management graders heartbeat |
|
19 | %w( announcements submissions configurations contests contest_management graders heartbeat |
|
20 | login main messages problems report site sites sources tasks groups |
|
20 | login main messages problems report site sites sources tasks groups |
|
21 | - test user_admin users tags).each do |controller| |
|
21 | + test user_admin users tags testcases).each do |controller| |
|
22 | Rails.application.config.assets.precompile += ["#{controller}.js", "#{controller}.css"] |
|
22 | Rails.application.config.assets.precompile += ["#{controller}.js", "#{controller}.css"] |
|
23 | end |
|
23 | end |
@@ -30,12 +30,13 | |||||
|
30 |
|
30 | ||
|
31 | def self.start_grader(env) |
|
31 | def self.start_grader(env) |
|
32 | GraderScript.call_grader "#{env} queue --err-log &" |
|
32 | GraderScript.call_grader "#{env} queue --err-log &" |
|
33 | GraderScript.call_grader "#{env} test_request -err-log &" |
|
33 | GraderScript.call_grader "#{env} test_request -err-log &" |
|
34 | end |
|
34 | end |
|
35 |
|
35 | ||
|
|
36 | + #call the import problem script | ||
|
36 | def self.call_import_problem(problem_name, |
|
37 | def self.call_import_problem(problem_name, |
|
37 | problem_dir, |
|
38 | problem_dir, |
|
38 | time_limit=1, |
|
39 | time_limit=1, |
|
39 | memory_limit=32, |
|
40 | memory_limit=32, |
|
40 | checker_name='text') |
|
41 | checker_name='text') |
|
41 | if GraderScript.grader_control_enabled? |
|
42 | if GraderScript.grader_control_enabled? |
@@ -5,12 +5,13 | |||||
|
5 | attr :log_msg |
|
5 | attr :log_msg |
|
6 |
|
6 | ||
|
7 | def initialize(problem) |
|
7 | def initialize(problem) |
|
8 | @problem = problem |
|
8 | @problem = problem |
|
9 | end |
|
9 | end |
|
10 |
|
10 | ||
|
|
11 | + #Create or update problem according to the parameter | ||
|
11 |
def import_from_file(tempfile, |
|
12 | def import_from_file(tempfile, |
|
12 |
time_limit, |
|
13 | time_limit, |
|
13 | memory_limit, |
|
14 | memory_limit, |
|
14 | checker_name='text', |
|
15 | checker_name='text', |
|
15 | import_to_db=false) |
|
16 | import_to_db=false) |
|
16 |
|
17 | ||
@@ -49,12 +50,13 | |||||
|
49 | def self.long_ext(filename) |
|
50 | def self.long_ext(filename) |
|
50 | i = filename.index('.') |
|
51 | i = filename.index('.') |
|
51 | len = filename.length |
|
52 | len = filename.length |
|
52 | return filename.slice(i..len) |
|
53 | return filename.slice(i..len) |
|
53 | end |
|
54 | end |
|
54 |
|
55 | ||
|
|
56 | + # extract an archive file located at +tempfile+ to the +raw_dir+ | ||
|
55 | def extract(tempfile) |
|
57 | def extract(tempfile) |
|
56 | testdata_filename = save_testdata_file(tempfile) |
|
58 | testdata_filename = save_testdata_file(tempfile) |
|
57 | ext = TestdataImporter.long_ext(tempfile.original_filename) |
|
59 | ext = TestdataImporter.long_ext(tempfile.original_filename) |
|
58 |
|
60 | ||
|
59 | extract_dir = File.join(GraderScript.raw_dir, @problem.name) |
|
61 | extract_dir = File.join(GraderScript.raw_dir, @problem.name) |
|
60 | if File.exists? extract_dir |
|
62 | if File.exists? extract_dir |
You need to be logged in to leave comments.
Login now