Description:
merge
Commit status:
[Not Reviewed]
References:
merge java
Comments:
0 Commit comments 0 Inline Comments
Unresolved TODOs:
There are no unresolved TODOs
Add another comment

r701:f26733606a76 - - 21 files changed: 132 inserted, 57 deleted

@@ -97,7 +97,7
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
@@ -165,7 +165,7
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
@@ -209,6 +209,10
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'
@@ -300,7 +304,7
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
@@ -52,6 +52,8
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)
@@ -41,6 +41,8
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
@@ -85,11 +85,10
85 end
85 end
86
86
87 def format_short_time(time)
87 def format_short_time(time)
88 - now = Time.now.gmtime
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
@@ -100,6 +99,10
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)
@@ -34,8 +34,8
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
@@ -1,13 +1,15
1 -
2 - if submission.nil?
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_short_time(submission.submitted_at.localtime)
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 - = "#{format_short_time(submission.graded_at.localtime)} "
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'
@@ -17,10 +19,10
17 = submission.grader_comment
19 = submission.grader_comment
18 = "]"
20 = "]"
19 %br
21 %br
20 - %strong View:
22 + %strong View:
21 - - if GraderConfiguration.show_grading_result
23 + - if GraderConfiguration.show_grading_result
22 - = link_to '[detailed result]', :action => 'result', :id => submission.id
24 + = link_to '[detailed result]', :action => 'result', :id => submission.id
23 - = link_to "#{t 'main.cmp_msg'}", {:action => 'compiler_msg', :id => submission.id}, {popup: true,class: 'btn btn-xs btn-info'}
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
@@ -46,6 +46,7
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')
@@ -12,6 +12,9
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
@@ -21,6 +21,7
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' } [?]
@@ -44,6 +45,10
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}")
@@ -49,7 +49,7
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 date added to
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
@@ -58,44 +58,53
58 &nbsp;&nbsp;&nbsp;
58 &nbsp;&nbsp;&nbsp;
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 available to
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-default'
73 + = submit_tag 'Add', name: 'add_group', class: 'btn btn-primary'
74 -
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'
75
78
76 - %table.table.table-hover
79 + %table.table.table-hover.datatable
77 - %tr{style: "text-align: left;"}
80 + %thead
78 - %th= check_box_tag 'select_all'
81 + %tr{style: "text-align: left;"}
79 - %th Name
82 + %th= check_box_tag 'select_all'
80 - %th Full name
83 + %th Name
81 - %th Available
84 + %th Full name
82 - %th Date added
85 + %th Tags
83 - - if GraderConfiguration.multicontests?
86 + %th Available
84 - %th Contests
87 + %th Date added
88 + - if GraderConfiguration.multicontests?
89 + %th Contests
85
90
86 - - num = 0
91 + %tbody
87 - - for problem in @problems
92 + - num = 0
88 - - num += 1
93 + - for problem in @problems
89 - %tr{:id => "row-prob-#{problem.id}", :name=> "prob-#{problem.id}"}
94 + - num += 1
90 - %td= check_box_tag "prob-#{problem.id}-#{num}"
95 + %tr{:id => "row-prob-#{problem.id}", :name=> "prob-#{problem.id}"}
91 - %td= problem.name
96 + %td= check_box_tag "prob-#{problem.id}-#{num}"
92 - %td= problem.full_name
97 + %td= problem.name
93 - %td= problem.available
98 + %td= problem.full_name
94 - %td= problem.date_added
95 - - if GraderConfiguration.multicontests?
96 %td
99 %td
97 - - problem.contests.each do |contest|
100 + - problem.tags.each do |t|
98 - = "(#{contest.name} [#{link_to 'x', :action => 'remove_contest', :id => problem.id, :contest_id => contest.id }])"
101 + %span.label.label-default= t.name
102 + %td= problem.available
103 + %td= problem.date_added
104 + - if GraderConfiguration.multicontests?
105 + %td
106 + - problem.contests.each do |contest|
107 + = "(#{contest.name} [#{link_to 'x', :action => 'remove_contest', :id => problem.id, :contest_id => contest.id }])"
99
108
100 :javascript
109 :javascript
101 $('.input-group.date').datetimepicker({
110 $('.input-group.date').datetimepicker({
@@ -104,4 +113,6
104 widgetPositioning: {horizontal: 'auto', vertical: 'bottom'},
113 widgetPositioning: {horizontal: 'auto', vertical: 'bottom'},
105
114
106 });
115 });
107 -
116 + $('.datatable').DataTable({
117 + paging: false
118 + });
@@ -32,6 +32,7
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
@@ -45,6 +46,7
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
@@ -12,6 +12,9
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
@@ -27,8 +30,40
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')
@@ -33,11 +33,11
33 .panel-body
33 .panel-body
34 .radio
34 .radio
35 %label
35 %label
36 - = radio_button_tag 'users', 'all', true
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
@@ -31,5 +31,6
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
@@ -27,14 +27,15
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 - - if @submission
35 + %div#latest_status
36 - = render :partial => 'submission_short',
36 + - if @submission
37 - :locals => {submission: @submission, problem_name: @problem.name, problem_id: @problem.id }
37 + = render :partial => 'submission_short',
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}})}")
@@ -65,7 +65,7
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
@@ -18,6 +18,6
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
@@ -33,6 +33,7
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,
@@ -8,8 +8,9
8 @problem = problem
8 @problem = problem
9 end
9 end
10
10
11 - def import_from_file(tempfile,
11 + #Create or update problem according to the parameter
12 - time_limit,
12 + def import_from_file(tempfile,
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)
@@ -52,6 +53,7
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)
You need to be logged in to leave comments. Login now