Description:
- start adding testcases into database - fix download button for score report
Commit status:
[Not Reviewed]
References:
Comments:
0 Commit comments 0 Inline Comments
Unresolved TODOs:
There are no unresolved TODOs
Add another comment

r607:350b2d080045 - - 7 files changed: 77 inserted, 6 deleted

@@ -0,0 +1,4
1 + class Testcase < ActiveRecord::Base
2 + belongs_to :problem
3 + attr_accessible :group, :input, :num, :score, :sol
4 + end
@@ -0,0 +1,15
1 + class CreateTestcases < ActiveRecord::Migration
2 + def change
3 + create_table :testcases do |t|
4 + t.references :problem
5 + t.integer :num
6 + t.integer :group
7 + t.integer :score
8 + t.text :input
9 + t.text :sol
10 +
11 + t.timestamps
12 + end
13 + add_index :testcases, :problem_id
14 + end
15 + end
@@ -0,0 +1,5
1 + require 'spec_helper'
2 +
3 + describe Testcases do
4 + pending "add some examples to (or delete) #{__FILE__}"
5 + end
@@ -1,156 +1,158
1 + require 'csv'
2 +
1 class ReportController < ApplicationController
3 class ReportController < ApplicationController
2
4
3 before_filter :authenticate
5 before_filter :authenticate
4
6
5 before_filter :admin_authorization, only: [:login_stat,:submission_stat, :stuck, :cheat_report, :cheat_scruntinize, :show_max_score]
7 before_filter :admin_authorization, only: [:login_stat,:submission_stat, :stuck, :cheat_report, :cheat_scruntinize, :show_max_score]
6
8
7 before_filter(only: [:problem_hof]) { |c|
9 before_filter(only: [:problem_hof]) { |c|
8 return false unless authenticate
10 return false unless authenticate
9
11
10 if GraderConfiguration["right.user_view_submission"]
12 if GraderConfiguration["right.user_view_submission"]
11 return true;
13 return true;
12 end
14 end
13
15
14 admin_authorization
16 admin_authorization
15 }
17 }
16
18
17 def max_score
19 def max_score
18 end
20 end
19
21
20 def current_score
22 def current_score
21 @problems = Problem.find_available_problems
23 @problems = Problem.find_available_problems
22 @users = User.includes(:contests).includes(:contest_stat).where(enabled: true)
24 @users = User.includes(:contests).includes(:contest_stat).where(enabled: true)
23 @scorearray = calculate_max_score(@problems, @users,0,0,true)
25 @scorearray = calculate_max_score(@problems, @users,0,0,true)
24
26
25 #rencer accordingly
27 #rencer accordingly
26 - if params[:commit] == 'download csv' then
28 + if params[:button] == 'download' then
27 csv = gen_csv_from_scorearray(@scorearray,@problems)
29 csv = gen_csv_from_scorearray(@scorearray,@problems)
28 send_data csv, filename: 'max_score.csv'
30 send_data csv, filename: 'max_score.csv'
29 else
31 else
30 #render template: 'user_admin/user_stat'
32 #render template: 'user_admin/user_stat'
31 render 'current_score'
33 render 'current_score'
32 end
34 end
33 end
35 end
34
36
35 def show_max_score
37 def show_max_score
36 #process parameters
38 #process parameters
37 #problems
39 #problems
38 @problems = []
40 @problems = []
39 params[:problem_id].each do |id|
41 params[:problem_id].each do |id|
40 next unless id.strip != ""
42 next unless id.strip != ""
41 pid = Problem.find_by_id(id.to_i)
43 pid = Problem.find_by_id(id.to_i)
42 @problems << pid if pid
44 @problems << pid if pid
43 end
45 end
44
46
45 #users
47 #users
46 @users = if params[:user] == "all" then
48 @users = if params[:user] == "all" then
47 User.find(:all, :include => [:contests, :contest_stat])
49 User.find(:all, :include => [:contests, :contest_stat])
48 else
50 else
49 User.includes(:contests).includes(:contest_stat).where(enabled: true)
51 User.includes(:contests).includes(:contest_stat).where(enabled: true)
50 end
52 end
51
53
52 #set up range from param
54 #set up range from param
53 since_id = params.fetch(:min_id, 0).to_i
55 since_id = params.fetch(:min_id, 0).to_i
54 until_id = params.fetch(:max_id, 0).to_i
56 until_id = params.fetch(:max_id, 0).to_i
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[:commit] == 'download csv' then
62 + if params[:button] == 'download' then
61 csv = gen_csv_from_scorearray(@scorearray,@problems)
63 csv = gen_csv_from_scorearray(@scorearray,@problems)
62 send_data csv, filename: 'max_score.csv'
64 send_data csv, filename: 'max_score.csv'
63 else
65 else
64 #render template: 'user_admin/user_stat'
66 #render template: 'user_admin/user_stat'
65 render 'max_score'
67 render 'max_score'
66 end
68 end
67
69
68 end
70 end
69
71
70 def score
72 def score
71 if params[:commit] == 'download csv'
73 if params[:commit] == 'download csv'
72 @problems = Problem.all
74 @problems = Problem.all
73 else
75 else
74 @problems = Problem.find_available_problems
76 @problems = Problem.find_available_problems
75 end
77 end
76 @users = User.includes(:contests, :contest_stat).where(enabled: true) #find(:all, :include => [:contests, :contest_stat]).where(enabled: true)
78 @users = User.includes(:contests, :contest_stat).where(enabled: true) #find(:all, :include => [:contests, :contest_stat]).where(enabled: true)
77 @scorearray = Array.new
79 @scorearray = Array.new
78 @users.each do |u|
80 @users.each do |u|
79 ustat = Array.new
81 ustat = Array.new
80 ustat[0] = u
82 ustat[0] = u
81 @problems.each do |p|
83 @problems.each do |p|
82 sub = Submission.find_last_by_user_and_problem(u.id,p.id)
84 sub = Submission.find_last_by_user_and_problem(u.id,p.id)
83 if (sub!=nil) and (sub.points!=nil) and p and p.full_score
85 if (sub!=nil) and (sub.points!=nil) and p and p.full_score
84 ustat << [(sub.points.to_f*100/p.full_score).round, (sub.points>=p.full_score)]
86 ustat << [(sub.points.to_f*100/p.full_score).round, (sub.points>=p.full_score)]
85 else
87 else
86 ustat << [0,false]
88 ustat << [0,false]
87 end
89 end
88 end
90 end
89 @scorearray << ustat
91 @scorearray << ustat
90 end
92 end
91 if params[:commit] == 'download csv' then
93 if params[:commit] == 'download csv' then
92 csv = gen_csv_from_scorearray(@scorearray,@problems)
94 csv = gen_csv_from_scorearray(@scorearray,@problems)
93 send_data csv, filename: 'last_score.csv'
95 send_data csv, filename: 'last_score.csv'
94 else
96 else
95 render template: 'user_admin/user_stat'
97 render template: 'user_admin/user_stat'
96 end
98 end
97
99
98 end
100 end
99
101
100 def login_stat
102 def login_stat
101 @logins = Array.new
103 @logins = Array.new
102
104
103 date_and_time = '%Y-%m-%d %H:%M'
105 date_and_time = '%Y-%m-%d %H:%M'
104 begin
106 begin
105 md = params[:since_datetime].match(/(\d+)-(\d+)-(\d+) (\d+):(\d+)/)
107 md = params[:since_datetime].match(/(\d+)-(\d+)-(\d+) (\d+):(\d+)/)
106 @since_time = Time.zone.local(md[1].to_i,md[2].to_i,md[3].to_i,md[4].to_i,md[5].to_i)
108 @since_time = Time.zone.local(md[1].to_i,md[2].to_i,md[3].to_i,md[4].to_i,md[5].to_i)
107 rescue
109 rescue
108 @since_time = DateTime.new(1000,1,1)
110 @since_time = DateTime.new(1000,1,1)
109 end
111 end
110 begin
112 begin
111 md = params[:until_datetime].match(/(\d+)-(\d+)-(\d+) (\d+):(\d+)/)
113 md = params[:until_datetime].match(/(\d+)-(\d+)-(\d+) (\d+):(\d+)/)
112 @until_time = Time.zone.local(md[1].to_i,md[2].to_i,md[3].to_i,md[4].to_i,md[5].to_i)
114 @until_time = Time.zone.local(md[1].to_i,md[2].to_i,md[3].to_i,md[4].to_i,md[5].to_i)
113 rescue
115 rescue
114 @until_time = DateTime.new(3000,1,1)
116 @until_time = DateTime.new(3000,1,1)
115 end
117 end
116
118
117 User.all.each do |user|
119 User.all.each do |user|
118 @logins << { id: user.id,
120 @logins << { id: user.id,
119 login: user.login,
121 login: user.login,
120 full_name: user.full_name,
122 full_name: user.full_name,
121 count: Login.where("user_id = ? AND created_at >= ? AND created_at <= ?",
123 count: Login.where("user_id = ? AND created_at >= ? AND created_at <= ?",
122 user.id,@since_time,@until_time)
124 user.id,@since_time,@until_time)
123 .count(:id),
125 .count(:id),
124 min: Login.where("user_id = ? AND created_at >= ? AND created_at <= ?",
126 min: Login.where("user_id = ? AND created_at >= ? AND created_at <= ?",
125 user.id,@since_time,@until_time)
127 user.id,@since_time,@until_time)
126 .minimum(:created_at),
128 .minimum(:created_at),
127 max: Login.where("user_id = ? AND created_at >= ? AND created_at <= ?",
129 max: Login.where("user_id = ? AND created_at >= ? AND created_at <= ?",
128 user.id,@since_time,@until_time)
130 user.id,@since_time,@until_time)
129 .maximum(:created_at),
131 .maximum(:created_at),
130 ip: Login.where("user_id = ? AND created_at >= ? AND created_at <= ?",
132 ip: Login.where("user_id = ? AND created_at >= ? AND created_at <= ?",
131 user.id,@since_time,@until_time)
133 user.id,@since_time,@until_time)
132 .select(:ip_address).uniq
134 .select(:ip_address).uniq
133
135
134 }
136 }
135 end
137 end
136 end
138 end
137
139
138 def submission_stat
140 def submission_stat
139
141
140 date_and_time = '%Y-%m-%d %H:%M'
142 date_and_time = '%Y-%m-%d %H:%M'
141 begin
143 begin
142 @since_time = DateTime.strptime(params[:since_datetime],date_and_time)
144 @since_time = DateTime.strptime(params[:since_datetime],date_and_time)
143 rescue
145 rescue
144 @since_time = DateTime.new(1000,1,1)
146 @since_time = DateTime.new(1000,1,1)
145 end
147 end
146 begin
148 begin
147 @until_time = DateTime.strptime(params[:until_datetime],date_and_time)
149 @until_time = DateTime.strptime(params[:until_datetime],date_and_time)
148 rescue
150 rescue
149 @until_time = DateTime.new(3000,1,1)
151 @until_time = DateTime.new(3000,1,1)
150 end
152 end
151
153
152 @submissions = {}
154 @submissions = {}
153
155
154 User.find_each do |user|
156 User.find_each do |user|
155 @submissions[user.id] = { login: user.login, full_name: user.full_name, count: 0, sub: { } }
157 @submissions[user.id] = { login: user.login, full_name: user.full_name, count: 0, sub: { } }
156 end
158 end
@@ -392,97 +394,128
392 UNION
394 UNION
393 SELECT s.id,s.user_id,s.ip_address,s.submitted_at,s.problem_id
395 SELECT s.id,s.user_id,s.ip_address,s.submitted_at,s.problem_id
394 FROM submissions s INNER JOIN
396 FROM submissions s INNER JOIN
395 (SELECT l.ip_address,COUNT(DISTINCT u.id) as count
397 (SELECT l.ip_address,COUNT(DISTINCT u.id) as count
396 FROM logins l
398 FROM logins l
397 INNER JOIN users u ON l.user_id = u.id
399 INNER JOIN users u ON l.user_id = u.id
398 WHERE l.created_at >= ? and l.created_at <= ?
400 WHERE l.created_at >= ? and l.created_at <= ?
399 GROUP BY l.ip_address
401 GROUP BY l.ip_address
400 HAVING count > 1
402 HAVING count > 1
401 ) ml on ml.ip_address = s.ip_address
403 ) ml on ml.ip_address = s.ip_address
402 WHERE s.submitted_at >= ? and s.submitted_at <= ?
404 WHERE s.submitted_at >= ? and s.submitted_at <= ?
403 ORDER BY ip_address,submitted_at
405 ORDER BY ip_address,submitted_at
404 SQL
406 SQL
405 @subs = Submission.joins(:problem).find_by_sql([st,@since_time,@until_time,
407 @subs = Submission.joins(:problem).find_by_sql([st,@since_time,@until_time,
406 @since_time,@until_time,
408 @since_time,@until_time,
407 @since_time,@until_time,
409 @since_time,@until_time,
408 @since_time,@until_time])
410 @since_time,@until_time])
409
411
410 end
412 end
411
413
412 def cheat_scruntinize
414 def cheat_scruntinize
413 #convert date & time
415 #convert date & time
414 date_and_time = '%Y-%m-%d %H:%M'
416 date_and_time = '%Y-%m-%d %H:%M'
415 begin
417 begin
416 md = params[:since_datetime].match(/(\d+)-(\d+)-(\d+) (\d+):(\d+)/)
418 md = params[:since_datetime].match(/(\d+)-(\d+)-(\d+) (\d+):(\d+)/)
417 @since_time = Time.zone.local(md[1].to_i,md[2].to_i,md[3].to_i,md[4].to_i,md[5].to_i)
419 @since_time = Time.zone.local(md[1].to_i,md[2].to_i,md[3].to_i,md[4].to_i,md[5].to_i)
418 rescue
420 rescue
419 @since_time = Time.zone.now.ago( 90.minutes)
421 @since_time = Time.zone.now.ago( 90.minutes)
420 end
422 end
421 begin
423 begin
422 md = params[:until_datetime].match(/(\d+)-(\d+)-(\d+) (\d+):(\d+)/)
424 md = params[:until_datetime].match(/(\d+)-(\d+)-(\d+) (\d+):(\d+)/)
423 @until_time = Time.zone.local(md[1].to_i,md[2].to_i,md[3].to_i,md[4].to_i,md[5].to_i)
425 @until_time = Time.zone.local(md[1].to_i,md[2].to_i,md[3].to_i,md[4].to_i,md[5].to_i)
424 rescue
426 rescue
425 @until_time = Time.zone.now
427 @until_time = Time.zone.now
426 end
428 end
427
429
428 #convert sid
430 #convert sid
429 @sid = params[:SID].split(/[,\s]/) if params[:SID]
431 @sid = params[:SID].split(/[,\s]/) if params[:SID]
430 unless @sid and @sid.size > 0
432 unless @sid and @sid.size > 0
431 return
433 return
432 redirect_to actoin: :cheat_scruntinize
434 redirect_to actoin: :cheat_scruntinize
433 flash[:notice] = 'Please enter at least 1 student id'
435 flash[:notice] = 'Please enter at least 1 student id'
434 end
436 end
435 mark = Array.new(@sid.size,'?')
437 mark = Array.new(@sid.size,'?')
436 condition = "(u.login = " + mark.join(' OR u.login = ') + ')'
438 condition = "(u.login = " + mark.join(' OR u.login = ') + ')'
437
439
438 @st = <<-SQL
440 @st = <<-SQL
439 SELECT l.created_at as submitted_at ,-1 as id,u.login,u.full_name,l.ip_address,"" as problem_id,"" as points,l.user_id
441 SELECT l.created_at as submitted_at ,-1 as id,u.login,u.full_name,l.ip_address,"" as problem_id,"" as points,l.user_id
440 FROM logins l INNER JOIN users u on l.user_id = u.id
442 FROM logins l INNER JOIN users u on l.user_id = u.id
441 WHERE l.created_at >= ? AND l.created_at <= ? AND #{condition}
443 WHERE l.created_at >= ? AND l.created_at <= ? AND #{condition}
442 UNION
444 UNION
443 SELECT s.submitted_at,s.id,u.login,u.full_name,s.ip_address,s.problem_id,s.points,s.user_id
445 SELECT s.submitted_at,s.id,u.login,u.full_name,s.ip_address,s.problem_id,s.points,s.user_id
444 FROM submissions s INNER JOIN users u ON s.user_id = u.id
446 FROM submissions s INNER JOIN users u ON s.user_id = u.id
445 WHERE s.submitted_at >= ? AND s.submitted_at <= ? AND #{condition}
447 WHERE s.submitted_at >= ? AND s.submitted_at <= ? AND #{condition}
446 ORDER BY submitted_at
448 ORDER BY submitted_at
447 SQL
449 SQL
448
450
449 p = [@st,@since_time,@until_time] + @sid + [@since_time,@until_time] + @sid
451 p = [@st,@since_time,@until_time] + @sid + [@since_time,@until_time] + @sid
450 @logs = Submission.joins(:problem).find_by_sql(p)
452 @logs = Submission.joins(:problem).find_by_sql(p)
451
453
452
454
453
455
454
456
455
457
456 end
458 end
457
459
458 protected
460 protected
459
461
460 def calculate_max_score(problems, users,since_id,until_id, get_last_score = false)
462 def calculate_max_score(problems, users,since_id,until_id, get_last_score = false)
461 scorearray = Array.new
463 scorearray = Array.new
462 users.each do |u|
464 users.each do |u|
463 ustat = Array.new
465 ustat = Array.new
464 ustat[0] = u
466 ustat[0] = u
465 problems.each do |p|
467 problems.each do |p|
466 unless get_last_score
468 unless get_last_score
467 #get max score
469 #get max score
468 max_points = 0
470 max_points = 0
469 Submission.find_in_range_by_user_and_problem(u.id,p.id,since_id,until_id).each do |sub|
471 Submission.find_in_range_by_user_and_problem(u.id,p.id,since_id,until_id).each do |sub|
470 max_points = sub.points if sub and sub.points and (sub.points > max_points)
472 max_points = sub.points if sub and sub.points and (sub.points > max_points)
471 end
473 end
472 ustat << [(max_points.to_f*100/p.full_score).round, (max_points>=p.full_score)]
474 ustat << [(max_points.to_f*100/p.full_score).round, (max_points>=p.full_score)]
473 else
475 else
474 #get latest score
476 #get latest score
475 sub = Submission.find_last_by_user_and_problem(u.id,p.id)
477 sub = Submission.find_last_by_user_and_problem(u.id,p.id)
476 if (sub!=nil) and (sub.points!=nil) and p and p.full_score
478 if (sub!=nil) and (sub.points!=nil) and p and p.full_score
477 ustat << [(sub.points.to_f*100/p.full_score).round, (sub.points>=p.full_score)]
479 ustat << [(sub.points.to_f*100/p.full_score).round, (sub.points>=p.full_score)]
478 else
480 else
479 ustat << [0,false]
481 ustat << [0,false]
480 end
482 end
481 end
483 end
482 end
484 end
483 scorearray << ustat
485 scorearray << ustat
484 end
486 end
485 return scorearray
487 return scorearray
486 end
488 end
487
489
490 + def gen_csv_from_scorearray(scorearray,problem)
491 + CSV.generate do |csv|
492 + #add header
493 + header = ['User','Name', 'Activated?', 'Logged in', 'Contest']
494 + problem.each { |p| header << p.name }
495 + header += ['Total','Passed']
496 + csv << header
497 + #add data
498 + scorearray.each do |sc|
499 + total = num_passed = 0
500 + row = Array.new
501 + sc.each_index do |i|
502 + if i == 0
503 + row << sc[i].login
504 + row << sc[i].full_name
505 + row << sc[i].activated
506 + row << (sc[i].try(:contest_stat).try(:started_at)!=nil ? 'yes' : 'no')
507 + row << sc[i].contests.collect {|c| c.name}.join(', ')
508 + else
509 + row << sc[i][0]
510 + total += sc[i][0]
511 + num_passed += 1 if sc[i][1]
512 + end
513 + end
514 + row << total
515 + row << num_passed
516 + csv << row
517 + end
518 + end
519 + end
520 +
488 end
521 end
@@ -1,101 +1,102
1 class Problem < ActiveRecord::Base
1 class Problem < ActiveRecord::Base
2
2
3 belongs_to :description
3 belongs_to :description
4 has_and_belongs_to_many :contests, :uniq => true
4 has_and_belongs_to_many :contests, :uniq => true
5 has_many :test_pairs, :dependent => :delete_all
5 has_many :test_pairs, :dependent => :delete_all
6 + has_many :testcases, :dependent => :destroy
6
7
7 validates_presence_of :name
8 validates_presence_of :name
8 validates_format_of :name, :with => /^\w+$/
9 validates_format_of :name, :with => /^\w+$/
9 validates_presence_of :full_name
10 validates_presence_of :full_name
10
11
11 scope :available, :conditions => {:available => true}
12 scope :available, :conditions => {:available => true}
12
13
13 DEFAULT_TIME_LIMIT = 1
14 DEFAULT_TIME_LIMIT = 1
14 DEFAULT_MEMORY_LIMIT = 32
15 DEFAULT_MEMORY_LIMIT = 32
15
16
16 def self.find_available_problems
17 def self.find_available_problems
17 Problem.available.all(:order => "date_added DESC, name ASC")
18 Problem.available.all(:order => "date_added DESC, name ASC")
18 end
19 end
19
20
20 def self.create_from_import_form_params(params, old_problem=nil)
21 def self.create_from_import_form_params(params, old_problem=nil)
21 org_problem = old_problem || Problem.new
22 org_problem = old_problem || Problem.new
22 import_params, problem = Problem.extract_params_and_check(params,
23 import_params, problem = Problem.extract_params_and_check(params,
23 org_problem)
24 org_problem)
24
25
25 if !problem.errors.empty?
26 if !problem.errors.empty?
26 return problem, 'Error importing'
27 return problem, 'Error importing'
27 end
28 end
28
29
29 problem.full_score = 100
30 problem.full_score = 100
30 problem.date_added = Time.new
31 problem.date_added = Time.new
31 problem.test_allowed = true
32 problem.test_allowed = true
32 problem.output_only = false
33 problem.output_only = false
33 problem.available = false
34 problem.available = false
34
35
35 if not problem.save
36 if not problem.save
36 return problem, 'Error importing'
37 return problem, 'Error importing'
37 end
38 end
38
39
39 import_to_db = params.has_key? :import_to_db
40 import_to_db = params.has_key? :import_to_db
40
41
41 importer = TestdataImporter.new(problem)
42 importer = TestdataImporter.new(problem)
42
43
43 if not importer.import_from_file(import_params[:file],
44 if not importer.import_from_file(import_params[:file],
44 import_params[:time_limit],
45 import_params[:time_limit],
45 import_params[:memory_limit],
46 import_params[:memory_limit],
46 import_params[:checker_name],
47 import_params[:checker_name],
47 import_to_db)
48 import_to_db)
48 problem.errors.add(:base,'Import error.')
49 problem.errors.add(:base,'Import error.')
49 end
50 end
50
51
51 return problem, importer.log_msg
52 return problem, importer.log_msg
52 end
53 end
53
54
54 def self.download_file_basedir
55 def self.download_file_basedir
55 return "#{Rails.root}/data/tasks"
56 return "#{Rails.root}/data/tasks"
56 end
57 end
57
58
58 def get_submission_stat
59 def get_submission_stat
59 result = Hash.new
60 result = Hash.new
60 #total number of submission
61 #total number of submission
61 result[:total_sub] = Submission.where(problem_id: self.id).count
62 result[:total_sub] = Submission.where(problem_id: self.id).count
62 result[:attempted_user] = Submission.where(problem_id: self.id).group_by(:user_id)
63 result[:attempted_user] = Submission.where(problem_id: self.id).group_by(:user_id)
63 end
64 end
64
65
65 def long_name
66 def long_name
66 "[#{name}] #{full_name}"
67 "[#{name}] #{full_name}"
67 end
68 end
68
69
69 protected
70 protected
70
71
71 def self.to_i_or_default(st, default)
72 def self.to_i_or_default(st, default)
72 if st!=''
73 if st!=''
73 result = st.to_i
74 result = st.to_i
74 end
75 end
75 result ||= default
76 result ||= default
76 end
77 end
77
78
78 def self.to_f_or_default(st, default)
79 def self.to_f_or_default(st, default)
79 if st!=''
80 if st!=''
80 result = st.to_f
81 result = st.to_f
81 end
82 end
82 result ||= default
83 result ||= default
83 end
84 end
84
85
85 def self.extract_params_and_check(params, problem)
86 def self.extract_params_and_check(params, problem)
86 time_limit = Problem.to_f_or_default(params[:time_limit],
87 time_limit = Problem.to_f_or_default(params[:time_limit],
87 DEFAULT_TIME_LIMIT)
88 DEFAULT_TIME_LIMIT)
88 memory_limit = Problem.to_i_or_default(params[:memory_limit],
89 memory_limit = Problem.to_i_or_default(params[:memory_limit],
89 DEFAULT_MEMORY_LIMIT)
90 DEFAULT_MEMORY_LIMIT)
90
91
91 if time_limit<=0 or time_limit >60
92 if time_limit<=0 or time_limit >60
92 problem.errors.add(:base,'Time limit out of range.')
93 problem.errors.add(:base,'Time limit out of range.')
93 end
94 end
94
95
95 if memory_limit==0 and params[:memory_limit]!='0'
96 if memory_limit==0 and params[:memory_limit]!='0'
96 problem.errors.add(:base,'Memory limit format errors.')
97 problem.errors.add(:base,'Memory limit format errors.')
97 elsif memory_limit<=0 or memory_limit >512
98 elsif memory_limit<=0 or memory_limit >512
98 problem.errors.add(:base,'Memory limit out of range.')
99 problem.errors.add(:base,'Memory limit out of range.')
99 end
100 end
100
101
101 if params[:file]==nil or params[:file]==''
102 if params[:file]==nil or params[:file]==''
@@ -1,49 +1,49
1 %h1 Maximum score
1 %h1 Maximum score
2
2
3 = form_tag report_show_max_score_path
3 = form_tag report_show_max_score_path
4 .row
4 .row
5 .col-md-4
5 .col-md-4
6 .panel.panel-primary
6 .panel.panel-primary
7 .panel-heading
7 .panel-heading
8 Problems
8 Problems
9 .panel-body
9 .panel-body
10 %p
10 %p
11 Select problem(s) that we wish to know the score.
11 Select problem(s) that we wish to know the score.
12 = label_tag :problem_id, "Problems"
12 = label_tag :problem_id, "Problems"
13 = select_tag 'problem_id[]',
13 = select_tag 'problem_id[]',
14 - options_for_select(Problem.all.collect {|p| ["[#{p.name}] #{p.full_name}", p.id]}),
14 + options_for_select(Problem.all.collect {|p| ["[#{p.name}] #{p.full_name}", p.id]},params[:problem_id]),
15 { class: 'select2 form-control', multiple: "true" }
15 { class: 'select2 form-control', multiple: "true" }
16 .col-md-4
16 .col-md-4
17 .panel.panel-primary
17 .panel.panel-primary
18 .panel-heading
18 .panel-heading
19 Submission range
19 Submission range
20 .panel-body
20 .panel-body
21 %p
21 %p
22 Input minimum and maximum range of submission ID that should be included. A blank value for min and max means -1 and infinity, respectively.
22 Input minimum and maximum range of submission ID that should be included. A blank value for min and max means -1 and infinity, respectively.
23 .form-group
23 .form-group
24 = label_tag :from, "Min"
24 = label_tag :from, "Min"
25 = text_field_tag 'from_id', nil, class: "form-control"
25 = text_field_tag 'from_id', nil, class: "form-control"
26 .form-group
26 .form-group
27 = label_tag :from, "Max"
27 = label_tag :from, "Max"
28 = text_field_tag 'to_id', nil, class: "form-control"
28 = text_field_tag 'to_id', nil, class: "form-control"
29 .col-md-4
29 .col-md-4
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', true
36 = radio_button_tag 'users', 'all', true
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'
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"
44 + = button_tag 'Show', class: "btn btn-primary btn-large", value: "show"
45 - = button_tag 'Download CSV', class: "btn btn-primary btn-large"
45 + = button_tag 'Download CSV', class: "btn btn-primary btn-large", value: "download"
46
46
47 - if @scorearray
47 - if @scorearray
48 %h2 Result
48 %h2 Result
49 =render "score_table"
49 =render "score_table"
@@ -1,110 +1,110
1 # encoding: UTF-8
1 # encoding: UTF-8
2 # This file is auto-generated from the current state of the database. Instead
2 # This file is auto-generated from the current state of the database. Instead
3 # of editing this file, please use the migrations feature of Active Record to
3 # of editing this file, please use the migrations feature of Active Record to
4 # incrementally modify your database, and then regenerate this schema definition.
4 # incrementally modify your database, and then regenerate this schema definition.
5 #
5 #
6 # Note that this schema.rb definition is the authoritative source for your
6 # Note that this schema.rb definition is the authoritative source for your
7 # database schema. If you need to create the application database on another
7 # database schema. If you need to create the application database on another
8 # system, you should be using db:schema:load, not running all the migrations
8 # system, you should be using db:schema:load, not running all the migrations
9 # from scratch. The latter is a flawed and unsustainable approach (the more migrations
9 # from scratch. The latter is a flawed and unsustainable approach (the more migrations
10 # you'll amass, the slower it'll run and the greater likelihood for issues).
10 # you'll amass, the slower it'll run and the greater likelihood for issues).
11 #
11 #
12 # It's strongly recommended to check this file into your version control system.
12 # It's strongly recommended to check this file into your version control system.
13
13
14 - ActiveRecord::Schema.define(:version => 20161008050135) do
14 + ActiveRecord::Schema.define(:version => 20161014091417) do
15
15
16 create_table "announcements", :force => true do |t|
16 create_table "announcements", :force => true do |t|
17 t.string "author"
17 t.string "author"
18 t.text "body"
18 t.text "body"
19 t.boolean "published"
19 t.boolean "published"
20 t.datetime "created_at", :null => false
20 t.datetime "created_at", :null => false
21 t.datetime "updated_at", :null => false
21 t.datetime "updated_at", :null => false
22 t.boolean "frontpage", :default => false
22 t.boolean "frontpage", :default => false
23 t.boolean "contest_only", :default => false
23 t.boolean "contest_only", :default => false
24 t.string "title"
24 t.string "title"
25 t.string "notes"
25 t.string "notes"
26 end
26 end
27
27
28 create_table "contests", :force => true do |t|
28 create_table "contests", :force => true do |t|
29 t.string "title"
29 t.string "title"
30 t.boolean "enabled"
30 t.boolean "enabled"
31 t.datetime "created_at", :null => false
31 t.datetime "created_at", :null => false
32 t.datetime "updated_at", :null => false
32 t.datetime "updated_at", :null => false
33 t.string "name"
33 t.string "name"
34 end
34 end
35
35
36 create_table "contests_problems", :id => false, :force => true do |t|
36 create_table "contests_problems", :id => false, :force => true do |t|
37 t.integer "contest_id"
37 t.integer "contest_id"
38 t.integer "problem_id"
38 t.integer "problem_id"
39 end
39 end
40
40
41 create_table "contests_users", :id => false, :force => true do |t|
41 create_table "contests_users", :id => false, :force => true do |t|
42 t.integer "contest_id"
42 t.integer "contest_id"
43 t.integer "user_id"
43 t.integer "user_id"
44 end
44 end
45
45
46 create_table "countries", :force => true do |t|
46 create_table "countries", :force => true do |t|
47 t.string "name"
47 t.string "name"
48 t.datetime "created_at", :null => false
48 t.datetime "created_at", :null => false
49 t.datetime "updated_at", :null => false
49 t.datetime "updated_at", :null => false
50 end
50 end
51
51
52 create_table "descriptions", :force => true do |t|
52 create_table "descriptions", :force => true do |t|
53 t.text "body"
53 t.text "body"
54 t.boolean "markdowned"
54 t.boolean "markdowned"
55 t.datetime "created_at", :null => false
55 t.datetime "created_at", :null => false
56 t.datetime "updated_at", :null => false
56 t.datetime "updated_at", :null => false
57 end
57 end
58
58
59 create_table "grader_configurations", :force => true do |t|
59 create_table "grader_configurations", :force => true do |t|
60 t.string "key"
60 t.string "key"
61 t.string "value_type"
61 t.string "value_type"
62 t.string "value"
62 t.string "value"
63 t.datetime "created_at", :null => false
63 t.datetime "created_at", :null => false
64 t.datetime "updated_at", :null => false
64 t.datetime "updated_at", :null => false
65 t.text "description"
65 t.text "description"
66 end
66 end
67
67
68 create_table "grader_processes", :force => true do |t|
68 create_table "grader_processes", :force => true do |t|
69 t.string "host"
69 t.string "host"
70 t.integer "pid"
70 t.integer "pid"
71 t.string "mode"
71 t.string "mode"
72 t.boolean "active"
72 t.boolean "active"
73 t.datetime "created_at", :null => false
73 t.datetime "created_at", :null => false
74 t.datetime "updated_at", :null => false
74 t.datetime "updated_at", :null => false
75 t.integer "task_id"
75 t.integer "task_id"
76 t.string "task_type"
76 t.string "task_type"
77 t.boolean "terminated"
77 t.boolean "terminated"
78 end
78 end
79
79
80 add_index "grader_processes", ["host", "pid"], :name => "index_grader_processes_on_ip_and_pid"
80 add_index "grader_processes", ["host", "pid"], :name => "index_grader_processes_on_ip_and_pid"
81
81
82 create_table "heart_beats", :force => true do |t|
82 create_table "heart_beats", :force => true do |t|
83 t.integer "user_id"
83 t.integer "user_id"
84 t.string "ip_address"
84 t.string "ip_address"
85 t.datetime "created_at", :null => false
85 t.datetime "created_at", :null => false
86 t.datetime "updated_at", :null => false
86 t.datetime "updated_at", :null => false
87 t.string "status"
87 t.string "status"
88 end
88 end
89
89
90 add_index "heart_beats", ["updated_at"], :name => "index_heart_beats_on_updated_at"
90 add_index "heart_beats", ["updated_at"], :name => "index_heart_beats_on_updated_at"
91
91
92 create_table "languages", :force => true do |t|
92 create_table "languages", :force => true do |t|
93 t.string "name", :limit => 10
93 t.string "name", :limit => 10
94 t.string "pretty_name"
94 t.string "pretty_name"
95 t.string "ext", :limit => 10
95 t.string "ext", :limit => 10
96 t.string "common_ext"
96 t.string "common_ext"
97 end
97 end
98
98
99 create_table "logins", :force => true do |t|
99 create_table "logins", :force => true do |t|
100 t.integer "user_id"
100 t.integer "user_id"
101 t.string "ip_address"
101 t.string "ip_address"
102 t.datetime "created_at", :null => false
102 t.datetime "created_at", :null => false
103 t.datetime "updated_at", :null => false
103 t.datetime "updated_at", :null => false
104 end
104 end
105
105
106 create_table "messages", :force => true do |t|
106 create_table "messages", :force => true do |t|
107 t.integer "sender_id"
107 t.integer "sender_id"
108 t.integer "receiver_id"
108 t.integer "receiver_id"
109 t.integer "replying_message_id"
109 t.integer "replying_message_id"
110 t.text "body"
110 t.text "body"
@@ -143,125 +143,138
143 t.string "name"
143 t.string "name"
144 end
144 end
145
145
146 create_table "roles_users", :id => false, :force => true do |t|
146 create_table "roles_users", :id => false, :force => true do |t|
147 t.integer "role_id"
147 t.integer "role_id"
148 t.integer "user_id"
148 t.integer "user_id"
149 end
149 end
150
150
151 add_index "roles_users", ["user_id"], :name => "index_roles_users_on_user_id"
151 add_index "roles_users", ["user_id"], :name => "index_roles_users_on_user_id"
152
152
153 create_table "sessions", :force => true do |t|
153 create_table "sessions", :force => true do |t|
154 t.string "session_id"
154 t.string "session_id"
155 t.text "data"
155 t.text "data"
156 t.datetime "updated_at"
156 t.datetime "updated_at"
157 end
157 end
158
158
159 add_index "sessions", ["session_id"], :name => "index_sessions_on_session_id"
159 add_index "sessions", ["session_id"], :name => "index_sessions_on_session_id"
160 add_index "sessions", ["updated_at"], :name => "index_sessions_on_updated_at"
160 add_index "sessions", ["updated_at"], :name => "index_sessions_on_updated_at"
161
161
162 create_table "sites", :force => true do |t|
162 create_table "sites", :force => true do |t|
163 t.string "name"
163 t.string "name"
164 t.boolean "started"
164 t.boolean "started"
165 t.datetime "start_time"
165 t.datetime "start_time"
166 t.datetime "created_at", :null => false
166 t.datetime "created_at", :null => false
167 t.datetime "updated_at", :null => false
167 t.datetime "updated_at", :null => false
168 t.integer "country_id"
168 t.integer "country_id"
169 t.string "password"
169 t.string "password"
170 end
170 end
171
171
172 create_table "submission_view_logs", :force => true do |t|
172 create_table "submission_view_logs", :force => true do |t|
173 t.integer "user_id"
173 t.integer "user_id"
174 t.integer "submission_id"
174 t.integer "submission_id"
175 t.datetime "created_at", :null => false
175 t.datetime "created_at", :null => false
176 t.datetime "updated_at", :null => false
176 t.datetime "updated_at", :null => false
177 end
177 end
178
178
179 create_table "submissions", :force => true do |t|
179 create_table "submissions", :force => true do |t|
180 t.integer "user_id"
180 t.integer "user_id"
181 t.integer "problem_id"
181 t.integer "problem_id"
182 t.integer "language_id"
182 t.integer "language_id"
183 t.text "source"
183 t.text "source"
184 t.binary "binary"
184 t.binary "binary"
185 t.datetime "submitted_at"
185 t.datetime "submitted_at"
186 t.datetime "compiled_at"
186 t.datetime "compiled_at"
187 t.text "compiler_message"
187 t.text "compiler_message"
188 t.datetime "graded_at"
188 t.datetime "graded_at"
189 t.integer "points"
189 t.integer "points"
190 t.text "grader_comment"
190 t.text "grader_comment"
191 t.integer "number"
191 t.integer "number"
192 t.string "source_filename"
192 t.string "source_filename"
193 t.float "max_runtime"
193 t.float "max_runtime"
194 t.integer "peak_memory"
194 t.integer "peak_memory"
195 t.integer "effective_code_length"
195 t.integer "effective_code_length"
196 t.string "ip_address"
196 t.string "ip_address"
197 end
197 end
198
198
199 add_index "submissions", ["user_id", "problem_id", "number"], :name => "index_submissions_on_user_id_and_problem_id_and_number", :unique => true
199 add_index "submissions", ["user_id", "problem_id", "number"], :name => "index_submissions_on_user_id_and_problem_id_and_number", :unique => true
200 add_index "submissions", ["user_id", "problem_id"], :name => "index_submissions_on_user_id_and_problem_id"
200 add_index "submissions", ["user_id", "problem_id"], :name => "index_submissions_on_user_id_and_problem_id"
201
201
202 create_table "tasks", :force => true do |t|
202 create_table "tasks", :force => true do |t|
203 t.integer "submission_id"
203 t.integer "submission_id"
204 t.datetime "created_at"
204 t.datetime "created_at"
205 t.integer "status"
205 t.integer "status"
206 t.datetime "updated_at"
206 t.datetime "updated_at"
207 end
207 end
208
208
209 create_table "test_pairs", :force => true do |t|
209 create_table "test_pairs", :force => true do |t|
210 t.integer "problem_id"
210 t.integer "problem_id"
211 t.text "input", :limit => 16777215
211 t.text "input", :limit => 16777215
212 t.text "solution", :limit => 16777215
212 t.text "solution", :limit => 16777215
213 t.datetime "created_at", :null => false
213 t.datetime "created_at", :null => false
214 t.datetime "updated_at", :null => false
214 t.datetime "updated_at", :null => false
215 end
215 end
216
216
217 create_table "test_requests", :force => true do |t|
217 create_table "test_requests", :force => true do |t|
218 t.integer "user_id"
218 t.integer "user_id"
219 t.integer "problem_id"
219 t.integer "problem_id"
220 t.integer "submission_id"
220 t.integer "submission_id"
221 t.string "input_file_name"
221 t.string "input_file_name"
222 t.string "output_file_name"
222 t.string "output_file_name"
223 t.string "running_stat"
223 t.string "running_stat"
224 t.integer "status"
224 t.integer "status"
225 t.datetime "updated_at", :null => false
225 t.datetime "updated_at", :null => false
226 t.datetime "submitted_at"
226 t.datetime "submitted_at"
227 t.datetime "compiled_at"
227 t.datetime "compiled_at"
228 t.text "compiler_message"
228 t.text "compiler_message"
229 t.datetime "graded_at"
229 t.datetime "graded_at"
230 t.string "grader_comment"
230 t.string "grader_comment"
231 t.datetime "created_at", :null => false
231 t.datetime "created_at", :null => false
232 t.float "running_time"
232 t.float "running_time"
233 t.string "exit_status"
233 t.string "exit_status"
234 t.integer "memory_usage"
234 t.integer "memory_usage"
235 end
235 end
236
236
237 add_index "test_requests", ["user_id", "problem_id"], :name => "index_test_requests_on_user_id_and_problem_id"
237 add_index "test_requests", ["user_id", "problem_id"], :name => "index_test_requests_on_user_id_and_problem_id"
238
238
239 + create_table "testcases", :force => true do |t|
240 + t.integer "problem_id"
241 + t.integer "num"
242 + t.integer "group"
243 + t.integer "score"
244 + t.text "input"
245 + t.text "sol"
246 + t.datetime "created_at", :null => false
247 + t.datetime "updated_at", :null => false
248 + end
249 +
250 + add_index "testcases", ["problem_id"], :name => "index_testcases_on_problem_id"
251 +
239 create_table "user_contest_stats", :force => true do |t|
252 create_table "user_contest_stats", :force => true do |t|
240 t.integer "user_id"
253 t.integer "user_id"
241 t.datetime "started_at"
254 t.datetime "started_at"
242 t.datetime "created_at", :null => false
255 t.datetime "created_at", :null => false
243 t.datetime "updated_at", :null => false
256 t.datetime "updated_at", :null => false
244 t.boolean "forced_logout"
257 t.boolean "forced_logout"
245 end
258 end
246
259
247 create_table "users", :force => true do |t|
260 create_table "users", :force => true do |t|
248 t.string "login", :limit => 50
261 t.string "login", :limit => 50
249 t.string "full_name"
262 t.string "full_name"
250 t.string "hashed_password"
263 t.string "hashed_password"
251 t.string "salt", :limit => 5
264 t.string "salt", :limit => 5
252 t.string "alias"
265 t.string "alias"
253 t.string "email"
266 t.string "email"
254 t.integer "site_id"
267 t.integer "site_id"
255 t.integer "country_id"
268 t.integer "country_id"
256 t.boolean "activated", :default => false
269 t.boolean "activated", :default => false
257 t.datetime "created_at"
270 t.datetime "created_at"
258 t.datetime "updated_at"
271 t.datetime "updated_at"
259 t.boolean "enabled", :default => true
272 t.boolean "enabled", :default => true
260 t.string "remark"
273 t.string "remark"
261 t.string "last_ip"
274 t.string "last_ip"
262 t.string "section"
275 t.string "section"
263 end
276 end
264
277
265 add_index "users", ["login"], :name => "index_users_on_login", :unique => true
278 add_index "users", ["login"], :name => "index_users_on_login", :unique => true
266
279
267 end
280 end
You need to be logged in to leave comments. Login now