Description:
add current score by group
Commit status:
[Not Reviewed]
References:
Comments:
0 Commit comments 0 Inline Comments
Unresolved TODOs:
There are no unresolved TODOs
Add another comment

r762:c6677423b846 - - 10 files changed: 105 inserted, 24 deleted

@@ -0,0 +1,45
1 + .container-fluid
2 + .row
3 + .col-md-6
4 + %h1 Adding list of users
5 + .row
6 + .col-md-6
7 + .panel.panel-default
8 + .panel-heading
9 + .panel-title Info
10 + .panel-body
11 + %ul
12 + %li
13 + List of user information in this format:
14 + %tt user_id,name(,passwd(,alias(,remark)))
15 + %li
16 + Note that
17 + %tt passwd, alias
18 + and
19 + %tt remark
20 + is optional.
21 + %li
22 + When
23 + %tt passwd
24 + or
25 + %tt alias
26 + is empty, the original value will be used instead.
27 + %li
28 + If the users with the same user_id already exists, existing information will be overwritten.
29 +
30 + .row
31 + .col-md-6
32 + = form_tag :action => 'create_from_list' do
33 + .form-group
34 + = submit_tag 'Create following users',class: 'btn btn-success'
35 + .form-group
36 + .div.checkbox
37 + %label
38 + = check_box_tag :add_to_group
39 + Also add these users to the following group
40 + = select_tag "group_id", options_from_collection_for_select( Group.all, 'id','name',params[:group_name]), id: 'group_name',class: 'select2'
41 + .form-group
42 + = text_area_tag 'user_list', nil, :rows => 50, :cols => 80
43 + .col-md-6
44 +
45 +
@@ -1,68 +1,73
1 require 'csv'
1 require 'csv'
2
2
3 class ReportController < ApplicationController
3 class ReportController < ApplicationController
4
4
5 before_action :check_valid_login
5 before_action :check_valid_login
6
6
7 before_action :admin_authorization, only: [:login_stat,:submission_stat, :stuck, :cheat_report, :cheat_scruntinize, :show_max_score, :current_score]
7 before_action :admin_authorization, only: [:login_stat,:submission_stat, :stuck, :cheat_report, :cheat_scruntinize, :show_max_score, :current_score]
8
8
9 before_action(only: [:problem_hof]) { |c|
9 before_action(only: [:problem_hof]) { |c|
10 return false unless check_valid_login
10 return false unless check_valid_login
11
11
12 admin_authorization unless GraderConfiguration["right.user_view_submission"]
12 admin_authorization unless GraderConfiguration["right.user_view_submission"]
13 }
13 }
14
14
15 def max_score
15 def max_score
16 end
16 end
17
17
18 def current_score
18 def current_score
19 @problems = Problem.available_problems
19 @problems = Problem.available_problems
20 + if params[:group_id]
21 + @group = Group.find(params[:group_id])
22 + @users = @group.users.where(enabled: true)
23 + else
20 @users = User.includes(:contests).includes(:contest_stat).where(enabled: true)
24 @users = User.includes(:contests).includes(:contest_stat).where(enabled: true)
25 + end
21 @scorearray = calculate_max_score(@problems, @users,0,0,true)
26 @scorearray = calculate_max_score(@problems, @users,0,0,true)
22
27
23 #rencer accordingly
28 #rencer accordingly
24 if params[:button] == 'download' then
29 if params[:button] == 'download' then
25 csv = gen_csv_from_scorearray(@scorearray,@problems)
30 csv = gen_csv_from_scorearray(@scorearray,@problems)
26 send_data csv, filename: 'max_score.csv'
31 send_data csv, filename: 'max_score.csv'
27 else
32 else
28 #render template: 'user_admin/user_stat'
33 #render template: 'user_admin/user_stat'
29 render 'current_score'
34 render 'current_score'
30 end
35 end
31 end
36 end
32
37
33 def show_max_score
38 def show_max_score
34 #process parameters
39 #process parameters
35 #problems
40 #problems
36 @problems = []
41 @problems = []
37 if params[:problem_id]
42 if params[:problem_id]
38 params[:problem_id].each do |id|
43 params[:problem_id].each do |id|
39 next unless id.strip != ""
44 next unless id.strip != ""
40 pid = Problem.find_by_id(id.to_i)
45 pid = Problem.find_by_id(id.to_i)
41 @problems << pid if pid
46 @problems << pid if pid
42 end
47 end
43 end
48 end
44
49
45 #users
50 #users
46 @users = if params[:users] == "all" then
51 @users = if params[:users] == "all" then
47 User.includes(:contests).includes(:contest_stat)
52 User.includes(:contests).includes(:contest_stat)
48 else
53 else
49 User.includes(:contests).includes(:contest_stat).where(enabled: true)
54 User.includes(:contests).includes(:contest_stat).where(enabled: true)
50 end
55 end
51
56
52 #set up range from param
57 #set up range from param
53 @since_id = params.fetch(:from_id, 0).to_i
58 @since_id = params.fetch(:from_id, 0).to_i
54 @until_id = params.fetch(:to_id, 0).to_i
59 @until_id = params.fetch(:to_id, 0).to_i
55 @since_id = nil if @since_id == 0
60 @since_id = nil if @since_id == 0
56 @until_id = nil if @until_id == 0
61 @until_id = nil if @until_id == 0
57
62
58 #calculate the routine
63 #calculate the routine
59 @scorearray = calculate_max_score(@problems, @users, @since_id, @until_id)
64 @scorearray = calculate_max_score(@problems, @users, @since_id, @until_id)
60
65
61 #rencer accordingly
66 #rencer accordingly
62 if params[:button] == 'download' then
67 if params[:button] == 'download' then
63 csv = gen_csv_from_scorearray(@scorearray,@problems)
68 csv = gen_csv_from_scorearray(@scorearray,@problems)
64 send_data csv, filename: 'max_score.csv'
69 send_data csv, filename: 'max_score.csv'
65 else
70 else
66 #render template: 'user_admin/user_stat'
71 #render template: 'user_admin/user_stat'
67 render 'max_score'
72 render 'max_score'
68 end
73 end
@@ -1,75 +1,74
1 class TasksController < ApplicationController
1 class TasksController < ApplicationController
2
2
3 before_action :check_valid_login, :check_viewability
3 before_action :check_valid_login, :check_viewability
4
4
5 def index
5 def index
6 redirect_to :action => 'list'
6 redirect_to :action => 'list'
7 end
7 end
8
8
9 def list
9 def list
10 @problems = @user.available_problems
10 @problems = @user.available_problems
11 end
11 end
12
12
13 # this has contest-wide access control
13 # this has contest-wide access control
14 def view
14 def view
15 base_name = params[:file]
15 base_name = params[:file]
16 base_filename = File.basename("#{base_name}.#{params[:ext]}")
16 base_filename = File.basename("#{base_name}.#{params[:ext]}")
17 filename = "#{Problem.download_file_basedir}/#{base_filename}"
17 filename = "#{Problem.download_file_basedir}/#{base_filename}"
18
18
19 if !FileTest.exists?(filename)
19 if !FileTest.exists?(filename)
20 redirect_to :action => 'index' and return
20 redirect_to :action => 'index' and return
21 end
21 end
22
22
23 send_file_to_user(filename, base_filename)
23 send_file_to_user(filename, base_filename)
24 end
24 end
25
25
26 # this has problem-level access control
26 # this has problem-level access control
27 def download
27 def download
28 problem = Problem.find(params[:id])
28 problem = Problem.find(params[:id])
29 unless @current_user.can_view_problem? problem
29 unless @current_user.can_view_problem? problem
30 + flash[:notice] = 'You are not authorized to access this file'
30 redirect_to :action => 'index' and return
31 redirect_to :action => 'index' and return
31 end
32 end
32
33
33 base_name = params[:file]
34 base_name = params[:file]
34 base_filename = File.basename("#{base_name}.#{params[:ext]}")
35 base_filename = File.basename("#{base_name}.#{params[:ext]}")
35 filename = "#{Problem.download_file_basedir}/#{params[:id]}/#{base_filename}"
36 filename = "#{Problem.download_file_basedir}/#{params[:id]}/#{base_filename}"
36 - puts "SENDING: #{filename}"
37
37
38 if !FileTest.exists?(filename)
38 if !FileTest.exists?(filename)
39 + flash[:notice] = 'File does not exists'
39 redirect_to :action => 'index' and return
40 redirect_to :action => 'index' and return
40 end
41 end
41
42
42 - puts "SENDING: #{filename}"
43 -
44 send_file_to_user(filename, base_filename)
43 send_file_to_user(filename, base_filename)
45 end
44 end
46
45
47 protected
46 protected
48
47
49 def send_file_to_user(filename, base_filename)
48 def send_file_to_user(filename, base_filename)
50 if defined?(USE_APACHE_XSENDFILE) and USE_APACHE_XSENDFILE
49 if defined?(USE_APACHE_XSENDFILE) and USE_APACHE_XSENDFILE
51 response.headers['Content-Type'] = "application/force-download"
50 response.headers['Content-Type'] = "application/force-download"
52 response.headers['Content-Disposition'] = "attachment; filename=\"#{File.basename(filename)}\""
51 response.headers['Content-Disposition'] = "attachment; filename=\"#{File.basename(filename)}\""
53 response.headers["X-Sendfile"] = filename
52 response.headers["X-Sendfile"] = filename
54 response.headers['Content-length'] = File.size(filename)
53 response.headers['Content-length'] = File.size(filename)
55 render :nothing => true
54 render :nothing => true
56 else
55 else
57 if params[:ext]=='pdf'
56 if params[:ext]=='pdf'
58 content_type = 'application/pdf'
57 content_type = 'application/pdf'
59 else
58 else
60 content_type = 'application/octet-stream'
59 content_type = 'application/octet-stream'
61 end
60 end
62
61
63 send_file filename, :stream => false, :disposition => 'inline', :filename => base_filename, :type => content_type
62 send_file filename, :stream => false, :disposition => 'inline', :filename => base_filename, :type => content_type
64 end
63 end
65 end
64 end
66
65
67 def check_viewability
66 def check_viewability
68 @user = User.find(session[:user_id])
67 @user = User.find(session[:user_id])
69 if @user==nil or !GraderConfiguration.show_tasks_to?(@user)
68 if @user==nil or !GraderConfiguration.show_tasks_to?(@user)
70 redirect_to :controller => 'main', :action => 'list'
69 redirect_to :controller => 'main', :action => 'list'
71 return false
70 return false
72 end
71 end
73 end
72 end
74
73
75 end
74 end
@@ -15,149 +15,169
15 @users = User.paginate :page => params[:page]
15 @users = User.paginate :page => params[:page]
16 @paginated = true
16 @paginated = true
17 end
17 end
18 @users = User.all
18 @users = User.all
19 @hidden_columns = ['hashed_password', 'salt', 'created_at', 'updated_at']
19 @hidden_columns = ['hashed_password', 'salt', 'created_at', 'updated_at']
20 @contests = Contest.enabled
20 @contests = Contest.enabled
21 end
21 end
22
22
23 def active
23 def active
24 sessions = ActiveRecord::SessionStore::Session.where("updated_at >= ?", 60.minutes.ago)
24 sessions = ActiveRecord::SessionStore::Session.where("updated_at >= ?", 60.minutes.ago)
25 @users = []
25 @users = []
26 sessions.each do |session|
26 sessions.each do |session|
27 if session.data[:user_id]
27 if session.data[:user_id]
28 @users << User.find(session.data[:user_id])
28 @users << User.find(session.data[:user_id])
29 end
29 end
30 end
30 end
31 end
31 end
32
32
33 def show
33 def show
34 @user = User.find(params[:id])
34 @user = User.find(params[:id])
35 end
35 end
36
36
37 def new
37 def new
38 @user = User.new
38 @user = User.new
39 end
39 end
40
40
41 def create
41 def create
42 @user = User.new(user_params)
42 @user = User.new(user_params)
43 @user.activated = true
43 @user.activated = true
44 if @user.save
44 if @user.save
45 flash[:notice] = 'User was successfully created.'
45 flash[:notice] = 'User was successfully created.'
46 redirect_to :action => 'index'
46 redirect_to :action => 'index'
47 else
47 else
48 render :action => 'new'
48 render :action => 'new'
49 end
49 end
50 end
50 end
51
51
52 def clear_last_ip
52 def clear_last_ip
53 @user = User.find(params[:id])
53 @user = User.find(params[:id])
54 @user.last_ip = nil
54 @user.last_ip = nil
55 @user.save
55 @user.save
56 redirect_to action: 'index', page: params[:page]
56 redirect_to action: 'index', page: params[:page]
57 end
57 end
58
58
59 def create_from_list
59 def create_from_list
60 lines = params[:user_list]
60 lines = params[:user_list]
61
61
62 note = []
62 note = []
63 + error_note = []
64 + ok_user = []
63
65
64 lines.split("\n").each do |line|
66 lines.split("\n").each do |line|
65 items = line.chomp.split(',')
67 items = line.chomp.split(',')
66 if items.length>=2
68 if items.length>=2
67 login = items[0]
69 login = items[0]
68 full_name = items[1]
70 full_name = items[1]
69 remark =''
71 remark =''
70 user_alias = ''
72 user_alias = ''
71
73
72 added_random_password = false
74 added_random_password = false
73 if items.length >= 3 and items[2].chomp(" ").length > 0;
75 if items.length >= 3 and items[2].chomp(" ").length > 0;
74 password = items[2].chomp(" ")
76 password = items[2].chomp(" ")
75 else
77 else
76 password = random_password
78 password = random_password
77 add_random_password=true;
79 add_random_password=true;
78 end
80 end
79
81
80 if items.length>= 4 and items[3].chomp(" ").length > 0;
82 if items.length>= 4 and items[3].chomp(" ").length > 0;
81 user_alias = items[3].chomp(" ")
83 user_alias = items[3].chomp(" ")
82 else
84 else
83 user_alias = login
85 user_alias = login
84 end
86 end
85
87
86 if items.length>=5
88 if items.length>=5
87 remark = items[4].strip;
89 remark = items[4].strip;
88 end
90 end
89
91
90 user = User.find_by_login(login)
92 user = User.find_by_login(login)
91 if (user)
93 if (user)
92 user.full_name = full_name
94 user.full_name = full_name
93 user.password = password
95 user.password = password
94 user.remark = remark
96 user.remark = remark
95 else
97 else
96 user = User.new({:login => login,
98 user = User.new({:login => login,
97 :full_name => full_name,
99 :full_name => full_name,
98 :password => password,
100 :password => password,
99 :password_confirmation => password,
101 :password_confirmation => password,
100 :alias => user_alias,
102 :alias => user_alias,
101 :remark => remark})
103 :remark => remark})
102 end
104 end
103 user.activated = true
105 user.activated = true
104 - user.save
105
106
107 + if user.save
106 if added_random_password
108 if added_random_password
107 note << "'#{login}' (+)"
109 note << "'#{login}' (+)"
108 else
110 else
109 note << login
111 note << login
110 end
112 end
113 + ok_user << user
114 + else
115 + error_note << "#{login}"
116 + end
117 +
111 end
118 end
112 end
119 end
120 +
121 + #add to group
122 + if params[:add_to_group]
123 + group = Group.where(id: params[:group_id]).first
124 + if group
125 + group.users << ok_user
126 + end
127 + end
128 +
129 + # show flash
113 flash[:success] = 'User(s) ' + note.join(', ') +
130 flash[:success] = 'User(s) ' + note.join(', ') +
114 ' were successfully created. ' +
131 ' were successfully created. ' +
115 '( (+) - created with random passwords.)'
132 '( (+) - created with random passwords.)'
133 + if error_note.size > 0
134 + flash[:error] = "Following user(s) failed to be created: " + error_note.join(', ')
135 + end
116 redirect_to :action => 'index'
136 redirect_to :action => 'index'
117 end
137 end
118
138
119 def edit
139 def edit
120 @user = User.find(params[:id])
140 @user = User.find(params[:id])
121 end
141 end
122
142
123 def update
143 def update
124 @user = User.find(params[:id])
144 @user = User.find(params[:id])
125 if @user.update_attributes(user_params)
145 if @user.update_attributes(user_params)
126 flash[:notice] = 'User was successfully updated.'
146 flash[:notice] = 'User was successfully updated.'
127 redirect_to :action => 'show', :id => @user
147 redirect_to :action => 'show', :id => @user
128 else
148 else
129 render :action => 'edit'
149 render :action => 'edit'
130 end
150 end
131 end
151 end
132
152
133 def destroy
153 def destroy
134 User.find(params[:id]).destroy
154 User.find(params[:id]).destroy
135 redirect_to :action => 'index'
155 redirect_to :action => 'index'
136 end
156 end
137
157
138 def user_stat
158 def user_stat
139 if params[:commit] == 'download csv'
159 if params[:commit] == 'download csv'
140 @problems = Problem.all
160 @problems = Problem.all
141 else
161 else
142 @problems = Problem.available_problems
162 @problems = Problem.available_problems
143 end
163 end
144 @users = User.includes(:contests, :contest_stat).where(enabled: true)
164 @users = User.includes(:contests, :contest_stat).where(enabled: true)
145 @scorearray = Array.new
165 @scorearray = Array.new
146 @users.each do |u|
166 @users.each do |u|
147 ustat = Array.new
167 ustat = Array.new
148 ustat[0] = u
168 ustat[0] = u
149 @problems.each do |p|
169 @problems.each do |p|
150 sub = Submission.find_last_by_user_and_problem(u.id,p.id)
170 sub = Submission.find_last_by_user_and_problem(u.id,p.id)
151 if (sub!=nil) and (sub.points!=nil) and p and p.full_score
171 if (sub!=nil) and (sub.points!=nil) and p and p.full_score
152 ustat << [(sub.points.to_f*100/p.full_score).round, (sub.points>=p.full_score)]
172 ustat << [(sub.points.to_f*100/p.full_score).round, (sub.points>=p.full_score)]
153 else
173 else
154 ustat << [0,false]
174 ustat << [0,false]
155 end
175 end
156 end
176 end
157 @scorearray << ustat
177 @scorearray << ustat
158 end
178 end
159 if params[:commit] == 'download csv' then
179 if params[:commit] == 'download csv' then
160 csv = gen_csv_from_scorearray(@scorearray,@problems)
180 csv = gen_csv_from_scorearray(@scorearray,@problems)
161 send_data csv, filename: 'last_score.csv'
181 send_data csv, filename: 'last_score.csv'
162 else
182 else
163 render template: 'user_admin/user_stat'
183 render template: 'user_admin/user_stat'
@@ -1,19 +1,20
1 module MainHelper
1 module MainHelper
2
2
3 def link_to_description_if_any(name, problem, options={})
3 def link_to_description_if_any(name, problem, options={})
4 if !problem.url.blank?
4 if !problem.url.blank?
5 return link_to name, problem.url, options
5 return link_to name, problem.url, options
6 elsif !problem.description_filename.blank?
6 elsif !problem.description_filename.blank?
7 + #build a link to a problem (via task controller)
7 basename, ext = problem.description_filename.split('.')
8 basename, ext = problem.description_filename.split('.')
8 options[:controller] = 'tasks'
9 options[:controller] = 'tasks'
9 options[:action] = 'download'
10 options[:action] = 'download'
10 options[:id] = problem.id
11 options[:id] = problem.id
11 options[:file] = basename
12 options[:file] = basename
12 options[:ext] = ext
13 options[:ext] = ext
13 return link_to name, options
14 return link_to name, options
14 else
15 else
15 return ''
16 return ''
16 end
17 end
17 end
18 end
18
19
19 end
20 end
@@ -201,103 +201,108
201 end
201 end
202 end
202 end
203
203
204 def problem_in_user_contests?(problem)
204 def problem_in_user_contests?(problem)
205 problem_contests = problem.contests.all
205 problem_contests = problem.contests.all
206
206
207 if problem_contests.length == 0 # this is public contest
207 if problem_contests.length == 0 # this is public contest
208 return true
208 return true
209 end
209 end
210
210
211 contests.each do |contest|
211 contests.each do |contest|
212 if problem_contests.find {|c| c.id == contest.id }
212 if problem_contests.find {|c| c.id == contest.id }
213 return true
213 return true
214 end
214 end
215 end
215 end
216 return false
216 return false
217 end
217 end
218
218
219 def available_problems_group_by_contests
219 def available_problems_group_by_contests
220 contest_problems = []
220 contest_problems = []
221 pin = {}
221 pin = {}
222 contests.enabled.each do |contest|
222 contests.enabled.each do |contest|
223 available_problems = contest.problems.available
223 available_problems = contest.problems.available
224 contest_problems << {
224 contest_problems << {
225 :contest => contest,
225 :contest => contest,
226 :problems => available_problems
226 :problems => available_problems
227 }
227 }
228 available_problems.each {|p| pin[p.id] = true}
228 available_problems.each {|p| pin[p.id] = true}
229 end
229 end
230 other_avaiable_problems = Problem.available.find_all {|p| pin[p.id]==nil and p.contests.length==0}
230 other_avaiable_problems = Problem.available.find_all {|p| pin[p.id]==nil and p.contests.length==0}
231 contest_problems << {
231 contest_problems << {
232 :contest => nil,
232 :contest => nil,
233 :problems => other_avaiable_problems
233 :problems => other_avaiable_problems
234 }
234 }
235 return contest_problems
235 return contest_problems
236 end
236 end
237
237
238 def solve_all_available_problems?
238 def solve_all_available_problems?
239 available_problems.each do |p|
239 available_problems.each do |p|
240 u = self
240 u = self
241 sub = Submission.find_last_by_user_and_problem(u.id,p.id)
241 sub = Submission.find_last_by_user_and_problem(u.id,p.id)
242 return false if !p or !sub or sub.points < p.full_score
242 return false if !p or !sub or sub.points < p.full_score
243 end
243 end
244 return true
244 return true
245 end
245 end
246
246
247 #get a list of available problem
247 #get a list of available problem
248 def available_problems
248 def available_problems
249 + # first, we check if this is normal mode
249 if not GraderConfiguration.multicontests?
250 if not GraderConfiguration.multicontests?
251 +
252 + #if this is a normal mode
253 + #we show problem based on problem_group, if the config said so
250 if GraderConfiguration.use_problem_group?
254 if GraderConfiguration.use_problem_group?
251 return available_problems_in_group
255 return available_problems_in_group
252 else
256 else
253 return Problem.available_problems
257 return Problem.available_problems
254 end
258 end
255 else
259 else
260 + #this is multi contest mode
256 contest_problems = []
261 contest_problems = []
257 pin = {}
262 pin = {}
258 contests.enabled.each do |contest|
263 contests.enabled.each do |contest|
259 contest.problems.available.each do |problem|
264 contest.problems.available.each do |problem|
260 if not pin.has_key? problem.id
265 if not pin.has_key? problem.id
261 contest_problems << problem
266 contest_problems << problem
262 end
267 end
263 pin[problem.id] = true
268 pin[problem.id] = true
264 end
269 end
265 end
270 end
266 other_avaiable_problems = Problem.available.find_all {|p| pin[p.id]==nil and p.contests.length==0}
271 other_avaiable_problems = Problem.available.find_all {|p| pin[p.id]==nil and p.contests.length==0}
267 return contest_problems + other_avaiable_problems
272 return contest_problems + other_avaiable_problems
268 end
273 end
269 end
274 end
270
275
271 def available_problems_in_group
276 def available_problems_in_group
272 problem = []
277 problem = []
273 self.groups.each do |group|
278 self.groups.each do |group|
274 group.problems.where(available: true).each { |p| problem << p }
279 group.problems.where(available: true).each { |p| problem << p }
275 end
280 end
276 problem.uniq!
281 problem.uniq!
277 if problem
282 if problem
278 problem.sort! do |a,b|
283 problem.sort! do |a,b|
279 case
284 case
280 when a.date_added < b.date_added
285 when a.date_added < b.date_added
281 1
286 1
282 when a.date_added > b.date_added
287 when a.date_added > b.date_added
283 -1
288 -1
284 else
289 else
285 a.name <=> b.name
290 a.name <=> b.name
286 end
291 end
287 end
292 end
288 return problem
293 return problem
289 else
294 else
290 return []
295 return []
291 end
296 end
292 end
297 end
293
298
294 def can_view_problem?(problem)
299 def can_view_problem?(problem)
295 return true if admin?
300 return true if admin?
296 return available_problems.include? problem
301 return available_problems.include? problem
297 end
302 end
298
303
299 def self.clear_last_login
304 def self.clear_last_login
300 User.update_all(:last_ip => nil)
305 User.update_all(:last_ip => nil)
301 end
306 end
302
307
303 protected
308 protected
@@ -1,73 +1,80
1 - %p
1 + .container-fluid
2 - %b Name:
2 + .row
3 - = @group.name
3 + .col-md-6
4 - %p
4 + %h1 Group #{@group.name}
5 + .row
6 + .col-md-6
5 %b Description:
7 %b Description:
6 = @group.description
8 = @group.description
7 -
8 %br
9 %br
9 - = link_to 'Edit', edit_group_path(@group)
10 + = link_to 'Edit', edit_group_path(@group), class: 'btn btn-primary'
10 - \|
11 - = link_to 'Back', groups_path
12 -
13 .row
11 .row
14 .col-md-12
12 .col-md-12
15 %h1 Group details
13 %h1 Group details
16 .row
14 .row
17 .col-md-6
15 .col-md-6
18 .panel.panel-default
16 .panel.panel-default
19 .panel-heading
17 .panel-heading
20 .panel-title Users in this group
18 .panel-title Users in this group
21 .panel-body
19 .panel-body
20 + %ul
21 + %li
22 + If you want to add several users to a group, it may be easier to just re-import those users in
23 + = link_to 'New list of users', new_list_user_admin_index_path
24 + page
22 =form_tag add_user_group_path(@group), class: 'form-inline' do
25 =form_tag add_user_group_path(@group), class: 'form-inline' do
23 .form-group
26 .form-group
24 =label_tag :user_id, "User"
27 =label_tag :user_id, "User"
25 =select_tag :user_id, options_from_collection_for_select(User.all,'id','full_name'), class: 'select2'
28 =select_tag :user_id, options_from_collection_for_select(User.all,'id','full_name'), class: 'select2'
26 =submit_tag "Add",class: 'btn btn-primary'
29 =submit_tag "Add",class: 'btn btn-primary'
27
30
28
31
29 %table.table.table-hover
32 %table.table.table-hover
30 %thead
33 %thead
31 %tr
34 %tr
32 %th Login
35 %th Login
33 %th Full name
36 %th Full name
34 %th Remark
37 %th Remark
35 %th= link_to 'Remove All', remove_all_user_group_path(@group), method: :delete, :data => { :confirm => "Remove ALL USERS from group?" }, class: 'btn btn-danger btn-sm'
38 %th= link_to 'Remove All', remove_all_user_group_path(@group), method: :delete, :data => { :confirm => "Remove ALL USERS from group?" }, class: 'btn btn-danger btn-sm'
36
39
37 %tbody
40 %tbody
38 - @group.users.each do |user|
41 - @group.users.each do |user|
39 %tr
42 %tr
40 %td= user.login
43 %td= user.login
41 %td= user.full_name
44 %td= user.full_name
42 %td= user.remark
45 %td= user.remark
43 %td= link_to 'Remove', remove_user_group_path(@group,user), :method => :delete, :data => { :confirm => "Remove #{user.full_name}?" }, class: 'btn btn-danger btn-sm'
46 %td= link_to 'Remove', remove_user_group_path(@group,user), :method => :delete, :data => { :confirm => "Remove #{user.full_name}?" }, class: 'btn btn-danger btn-sm'
44 .col-md-6
47 .col-md-6
45 .panel.panel-default
48 .panel.panel-default
46 .panel-heading
49 .panel-heading
47 .panel-title Problems
50 .panel-title Problems
48 .panel-body
51 .panel-body
49 -
52 + %ul
53 + %li
54 + If you want to add several problem to a group, it may be easier to bulk manage them in the
55 + = link_to 'Bulk Manage', manage_problems_path
56 + page
50 =form_tag add_problem_group_path(@group), class: 'form-inline' do
57 =form_tag add_problem_group_path(@group), class: 'form-inline' do
51 .form-group
58 .form-group
52 =label_tag :problem_id, "Problem"
59 =label_tag :problem_id, "Problem"
53 =select_tag :problem_id, options_from_collection_for_select(Problem.all,'id','full_name'), class: 'select2'
60 =select_tag :problem_id, options_from_collection_for_select(Problem.all,'id','full_name'), class: 'select2'
54 =submit_tag "Add",class: 'btn btn-primary'
61 =submit_tag "Add",class: 'btn btn-primary'
55
62
56
63
57 %table.table.table-hover
64 %table.table.table-hover
58 %thead
65 %thead
59 %tr
66 %tr
60 %th name
67 %th name
61 %th Full name
68 %th Full name
62 %th Full score
69 %th Full score
63 %th= link_to 'Remove All', remove_all_problem_group_path(@group), method: :delete, :data => { :confirm => "Remove ALL PROBLEMS from group?" }, class: 'btn btn-danger btn-sm'
70 %th= link_to 'Remove All', remove_all_problem_group_path(@group), method: :delete, :data => { :confirm => "Remove ALL PROBLEMS from group?" }, class: 'btn btn-danger btn-sm'
64
71
65 %tbody
72 %tbody
66 - @group.problems.each do |problem|
73 - @group.problems.each do |problem|
67 %tr
74 %tr
68 %td= problem.name
75 %td= problem.name
69 %td= problem.full_name
76 %td= problem.full_name
70 %td= problem.full_score
77 %td= problem.full_score
71 %td= link_to 'Remove', remove_problem_group_path(@group,problem), :method => :delete, :data => { :confirm => "Remove #{problem.full_name}?" }, class: 'btn btn-danger btn-sm'
78 %td= link_to 'Remove', remove_problem_group_path(@group,problem), :method => :delete, :data => { :confirm => "Remove #{problem.full_name}?" }, class: 'btn btn-danger btn-sm'
72
79
73
80
@@ -1,3 +1,11
1 + .container-fluid
1 %h1 Current Score
2 %h1 Current Score
3 + = form_tag current_score_report_path, method: 'get' do
4 + Show only users from this group
5 + = select_tag "group_id", options_from_collection_for_select( Group.all, 'id','name',params[:group_name]), id: 'group_name',class: 'select2'
6 + = submit_tag 'Apply',class: 'btn btn-default'
7 +
8 + %br
9 +
2
10
3 = render "score_table"
11 = render "score_table"
@@ -90,97 +90,97
90 get 'direct_edit_problem/:problem_id(/:user_id)', to: 'submissions#direct_edit_problem', as: 'direct_edit_problem'
90 get 'direct_edit_problem/:problem_id(/:user_id)', to: 'submissions#direct_edit_problem', as: 'direct_edit_problem'
91 get 'get_latest_submission_status/:uid/:pid', to: 'submissions#get_latest_submission_status', as: 'get_latest_submission_status'
91 get 'get_latest_submission_status/:uid/:pid', to: 'submissions#get_latest_submission_status', as: 'get_latest_submission_status'
92 end
92 end
93 end
93 end
94
94
95
95
96 #user admin
96 #user admin
97 resources :user_admin do
97 resources :user_admin do
98 collection do
98 collection do
99 match 'bulk_manage', via: [:get, :post]
99 match 'bulk_manage', via: [:get, :post]
100 get 'bulk_mail'
100 get 'bulk_mail'
101 get 'user_stat'
101 get 'user_stat'
102 get 'import'
102 get 'import'
103 get 'new_list'
103 get 'new_list'
104 get 'admin'
104 get 'admin'
105 get 'active'
105 get 'active'
106 get 'mass_mailing'
106 get 'mass_mailing'
107 get 'revoke_admin'
107 get 'revoke_admin'
108 post 'grant_admin'
108 post 'grant_admin'
109 match 'create_from_list', via: [:get, :post]
109 match 'create_from_list', via: [:get, :post]
110 match 'random_all_passwords', via: [:get, :post]
110 match 'random_all_passwords', via: [:get, :post]
111 end
111 end
112 member do
112 member do
113 get 'clear_last_ip'
113 get 'clear_last_ip'
114 end
114 end
115 end
115 end
116
116
117 resources :contest_management, only: [:index] do
117 resources :contest_management, only: [:index] do
118 collection do
118 collection do
119 get 'user_stat'
119 get 'user_stat'
120 get 'clear_stat'
120 get 'clear_stat'
121 get 'clear_all_stat'
121 get 'clear_all_stat'
122 get 'change_contest_mode'
122 get 'change_contest_mode'
123 end
123 end
124 end
124 end
125
125
126 #get 'user_admin', to: 'user_admin#index'
126 #get 'user_admin', to: 'user_admin#index'
127 #get 'user_admin/bulk_manage', to: 'user_admin#bulk_manage', as: 'bulk_manage_user_admin'
127 #get 'user_admin/bulk_manage', to: 'user_admin#bulk_manage', as: 'bulk_manage_user_admin'
128 #post 'user_admin', to: 'user_admin#create'
128 #post 'user_admin', to: 'user_admin#create'
129 #delete 'user_admin/:id', to: 'user_admin#destroy', as: 'user_admin_destroy'
129 #delete 'user_admin/:id', to: 'user_admin#destroy', as: 'user_admin_destroy'
130
130
131 #singular resource
131 #singular resource
132 #---- BEWARE ---- singular resource maps to plural controller by default, we can override by provide controller name directly
132 #---- BEWARE ---- singular resource maps to plural controller by default, we can override by provide controller name directly
133 #report
133 #report
134 resource :report, only: [], controller: 'report' do
134 resource :report, only: [], controller: 'report' do
135 get 'login'
135 get 'login'
136 get 'multiple_login'
136 get 'multiple_login'
137 get 'problem_hof/:id', action: 'problem_hof'
137 get 'problem_hof/:id', action: 'problem_hof'
138 - get 'current_score'
138 + get 'current_score(/:group_id)', action: 'current_score', as: 'current_score'
139 get 'max_score'
139 get 'max_score'
140 post 'show_max_score'
140 post 'show_max_score'
141 end
141 end
142 #get 'report/current_score', to: 'report#current_score', as: 'report_current_score'
142 #get 'report/current_score', to: 'report#current_score', as: 'report_current_score'
143 #get 'report/problem_hof(/:id)', to: 'report#problem_hof', as: 'report_problem_hof'
143 #get 'report/problem_hof(/:id)', to: 'report#problem_hof', as: 'report_problem_hof'
144 #get "report/login"
144 #get "report/login"
145 #get 'report/max_score', to: 'report#max_score', as: 'report_max_score'
145 #get 'report/max_score', to: 'report#max_score', as: 'report_max_score'
146 #post 'report/show_max_score', to: 'report#show_max_score', as: 'report_show_max_score'
146 #post 'report/show_max_score', to: 'report#show_max_score', as: 'report_show_max_score'
147
147
148 resource :main, only: [], controller: 'main' do
148 resource :main, only: [], controller: 'main' do
149 get 'login'
149 get 'login'
150 get 'logout'
150 get 'logout'
151 get 'list'
151 get 'list'
152 get 'submission(/:id)', action: 'submission', as: 'main_submission'
152 get 'submission(/:id)', action: 'submission', as: 'main_submission'
153 get 'announcements'
153 get 'announcements'
154 get 'help'
154 get 'help'
155 post 'submit'
155 post 'submit'
156 end
156 end
157 #main
157 #main
158 #get "main/list"
158 #get "main/list"
159 #get 'main/submission(/:id)', to: 'main#submission', as: 'main_submission'
159 #get 'main/submission(/:id)', to: 'main#submission', as: 'main_submission'
160 #post 'main/submit', to: 'main#submit'
160 #post 'main/submit', to: 'main#submit'
161 #get 'main/announcements', to: 'main#announcements'
161 #get 'main/announcements', to: 'main#announcements'
162
162
163
163
164 #
164 #
165 get 'tasks/view/:file.:ext' => 'tasks#view'
165 get 'tasks/view/:file.:ext' => 'tasks#view'
166 get 'tasks/download/:id/:file.:ext' => 'tasks#download'
166 get 'tasks/download/:id/:file.:ext' => 'tasks#download'
167 get 'heartbeat/:id/edit' => 'heartbeat#edit'
167 get 'heartbeat/:id/edit' => 'heartbeat#edit'
168
168
169 #grader
169 #grader
170 get 'graders/list', to: 'graders#list', as: 'grader_list'
170 get 'graders/list', to: 'graders#list', as: 'grader_list'
171 namespace :graders do
171 namespace :graders do
172 get 'task/:id/:type', action: 'task', as: 'task'
172 get 'task/:id/:type', action: 'task', as: 'task'
173 get 'view/:id/:type', action: 'view', as: 'view'
173 get 'view/:id/:type', action: 'view', as: 'view'
174 get 'clear/:id', action: 'clear', as: 'clear'
174 get 'clear/:id', action: 'clear', as: 'clear'
175 get 'stop'
175 get 'stop'
176 get 'stop_all'
176 get 'stop_all'
177 get 'clear_all'
177 get 'clear_all'
178 get 'clear_terminated'
178 get 'clear_terminated'
179 get 'start_grading'
179 get 'start_grading'
180 get 'start_exam'
180 get 'start_exam'
181
181
182 end
182 end
183
183
184
184
185 # See how all your routes lay out with "rake routes"
185 # See how all your routes lay out with "rake routes"
186
186
deleted file
You need to be logged in to leave comments. Login now