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

r793:8cbec24011e9 - - 4 files changed: 112 inserted, 87 deleted

@@ -0,0 +1,107
1 + - content_for :header do
2 + = stylesheet_link_tag 'tablesorter-theme.cafe'
3 + = javascript_include_tag 'local_jquery'
4 +
5 + %script{:type=>"text/javascript"}
6 + $(function () {
7 + $('#since_datetime').datetimepicker({ showButtonPanel: true, dateFormat: "yy-mm-dd", controlType: "slider"} );
8 + $('#until_datetime').datetimepicker({ showButtonPanel: true, dateFormat: "yy-mm-dd", controlType: "slider"} );
9 + $('#my_table').tablesorter({widthFixed: true, widgets: ['zebra']});
10 + $('#my_table2').tablesorter({widthFixed: true, widgets: ['zebra']});
11 + $('#sub_table').tablesorter({widthFixed: true, widgets: ['zebra']});
12 + });
13 +
14 + %h1 Login status
15 +
16 + .panel.panel-primary
17 + .panel-heading
18 + User ID and time rnage
19 + .panel-body
20 + = form_tag({session: :url }) do
21 + .row.form-group
22 + .col-md-2
23 + From Date:
24 + .col-md-4
25 + .input-group.date
26 + = text_field_tag :since_datetime, @since_time, class: 'form-control'
27 + %span.input-group-addon
28 + %span.glyphicon.glyphicon-calendar
29 + .row.form-group
30 + .col-md-2
31 + Until Date:
32 + .col-md-4
33 + .input-group.date
34 + = text_field_tag :until_datetime, @until_time, class: 'form-control'
35 + %span.input-group-addon
36 + %span.glyphicon.glyphicon-calendar
37 + .row.form-group
38 + .col-md-2
39 + IDs (separated by space):
40 + .col-md-10
41 + = text_field_tag 'SID', @sid, size: 40, class: 'form-control'
42 + .row.form-group
43 + .col-md-2
44 + .col-md-10
45 + =submit_tag 'query', class: 'btn btn-primary'
46 +
47 + -#
48 + %table
49 + %tr
50 + %td{style: 'width: 120px; font-weight: bold'}= 'Login date range'
51 + %td{align: 'right'} since:
52 + %td= text_field_tag 'since_datetime', @since_time, class: 'form-control datetimepicker'
53 + %tr
54 + %td
55 + %td{align: 'right'} until:
56 + %td= text_field_tag 'until_datetime', @until_time
57 + %tr
58 + %td
59 + %td
60 + %td Blank mean no condition
61 + %tr
62 + %td{style: 'width: 120px; font-weight: bold'}= "ID"
63 + %td{colspan: 2}= text_field_tag 'SID', @sid, size: 40
64 + %tr
65 + %td
66 + %td
67 + %td= submit_tag 'query'
68 +
69 +
70 + %h2 Logs
71 +
72 + - if @sid
73 + %table
74 + %tbody
75 + - @sid.each do |id|
76 + - user = User.where("login = ?",id).first
77 + %tr
78 + //%td= link_to id, controller: :user, action: :profile, id: id
79 + %td= link_to id, "https://www.nattee.net/java/users/profile/#{user.id}"
80 + %td= user.full_name
81 +
82 + //%table.tablesorter-cafe#my_table
83 + %table.info
84 + %thead
85 + %tr.info-head
86 + %th Time
87 + %th Action
88 + %th IP
89 + %th login
90 + %th name
91 + %th problem
92 + %th score
93 + %tbody
94 + - if @logs
95 + - @logs.each do |l|
96 + %tr{class: cycle('info-even','info-odd')}
97 + %td= l[:submitted_at].strftime "%Y.%b.%d %H:%M:%S"
98 + //%td= l[:id] == -1 ? "LOGIN" : link_to("submit #{l[:id]}", controller: 'graders' , action: 'submission', id: l[:id])
99 + %td= l[:id] == -1 ? "LOGIN" : link_to( "submit #{l[:id]}", "https://www.nattee.net/java/graders/submission/#{l[:id]}")
100 + %td= l[:ip_address]
101 + //%td= link_to l[:login], controller: 'users', action: 'profile', id: l[:id]
102 + %td= link_to( l[:login], "https://www.nattee.net/java/users/profile/#{l.user_id}")
103 + %td= l[:full_name]
104 + %td= l[:id] == -1 ? "" : l.problem.name
105 + %td= l[:id] == -1 ? "" : l.points * 100/ l.problem.full_score
106 +
107 +
@@ -1,201 +1,201
1 1 require 'csv'
2 2
3 3 class ReportController < ApplicationController
4 4
5 5 before_action :check_valid_login
6 6
7 7 before_action :admin_authorization, only: [:login_stat,:submission, :submission_query,
8 8 :login, :login_detail_query, :login_summary_query,
9 - :stuck, :cheat_report, :cheat_scruntinize, :show_max_score, :current_score]
9 + :stuck, :cheat_report, :cheat_scrutinize, :show_max_score, :current_score]
10 10
11 11 before_action(only: [:problem_hof]) { |c|
12 12 return false unless check_valid_login
13 13
14 14 admin_authorization unless GraderConfiguration["right.user_view_submission"]
15 15 }
16 16
17 17 def max_score
18 18 end
19 19
20 20 def current_score
21 21 @problems = Problem.available_problems
22 22 if params[:group_id]
23 23 @group = Group.find(params[:group_id])
24 24 @users = @group.users.where(enabled: true)
25 25 else
26 26 @users = User.includes(:contests).includes(:contest_stat).where(enabled: true)
27 27 end
28 28 @scorearray = calculate_max_score(@problems, @users,0,0,true)
29 29
30 30 #rencer accordingly
31 31 if params[:button] == 'download' then
32 32 csv = gen_csv_from_scorearray(@scorearray,@problems)
33 33 send_data csv, filename: 'max_score.csv'
34 34 else
35 35 #render template: 'user_admin/user_stat'
36 36 render 'current_score'
37 37 end
38 38 end
39 39
40 40 def show_max_score
41 41 #process parameters
42 42 #problems
43 43 @problems = []
44 44 if params[:problem_id]
45 45 params[:problem_id].each do |id|
46 46 next unless id.strip != ""
47 47 pid = Problem.find_by_id(id.to_i)
48 48 @problems << pid if pid
49 49 end
50 50 end
51 51
52 52 #users
53 53 @users = if params[:users] == "all" then
54 54 User.includes(:contests).includes(:contest_stat)
55 55 else
56 56 User.includes(:contests).includes(:contest_stat).where(enabled: true)
57 57 end
58 58
59 59 #set up range from param
60 60 @since_id = params.fetch(:from_id, 0).to_i
61 61 @until_id = params.fetch(:to_id, 0).to_i
62 62 @since_id = nil if @since_id == 0
63 63 @until_id = nil if @until_id == 0
64 64
65 65 #calculate the routine
66 66 @scorearray = calculate_max_score(@problems, @users, @since_id, @until_id)
67 67
68 68 #rencer accordingly
69 69 if params[:button] == 'download' then
70 70 csv = gen_csv_from_scorearray(@scorearray,@problems)
71 71 send_data csv, filename: 'max_score.csv'
72 72 else
73 73 #render template: 'user_admin/user_stat'
74 74 render 'max_score'
75 75 end
76 76
77 77 end
78 78
79 79 def score
80 80 if params[:commit] == 'download csv'
81 81 @problems = Problem.all
82 82 else
83 83 @problems = Problem.available_problems
84 84 end
85 85 @users = User.includes(:contests, :contest_stat).where(enabled: true)
86 86 @scorearray = Array.new
87 87 @users.each do |u|
88 88 ustat = Array.new
89 89 ustat[0] = u
90 90 @problems.each do |p|
91 91 sub = Submission.find_last_by_user_and_problem(u.id,p.id)
92 92 if (sub!=nil) and (sub.points!=nil) and p and p.full_score
93 93 ustat << [(sub.points.to_f*100/p.full_score).round, (sub.points>=p.full_score)]
94 94 else
95 95 ustat << [0,false]
96 96 end
97 97 end
98 98 @scorearray << ustat
99 99 end
100 100 if params[:commit] == 'download csv' then
101 101 csv = gen_csv_from_scorearray(@scorearray,@problems)
102 102 send_data csv, filename: 'last_score.csv'
103 103 else
104 104 render template: 'user_admin/user_stat'
105 105 end
106 106
107 107 end
108 108
109 109 def login
110 110 end
111 111
112 112 def login_summary_query
113 113 @users = Array.new
114 114
115 115 date_and_time = '%Y-%m-%d %H:%M'
116 116 begin
117 117 md = params[:since_datetime].match(/(\d+)-(\d+)-(\d+) (\d+):(\d+)/)
118 118 @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)
119 119 rescue
120 120 @since_time = DateTime.new(1000,1,1)
121 121 end
122 122 begin
123 123 md = params[:until_datetime].match(/(\d+)-(\d+)-(\d+) (\d+):(\d+)/)
124 124 @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)
125 125 rescue
126 126 @until_time = DateTime.new(3000,1,1)
127 127 end
128 128
129 129 record = User
130 130 .left_outer_joins(:logins).group('users.id')
131 131 .where("logins.created_at >= ? AND logins.created_at <= ?",@since_time, @until_time)
132 132 case params[:users]
133 133 when 'enabled'
134 134 record = record.where(enabled: true)
135 135 when 'group'
136 136 record = record.joins(:groups).where(groups: {id: params[:groups]}) if params[:groups]
137 137 end
138 138
139 139 record = record.pluck("users.id,users.login,users.full_name,count(logins.created_at),min(logins.created_at),max(logins.created_at)")
140 140 record.each do |user|
141 141 x = Login.where("user_id = ? AND created_at >= ? AND created_at <= ?",
142 142 user[0],@since_time,@until_time)
143 143 .pluck(:ip_address).uniq
144 144 @users << { id: user[0],
145 145 login: user[1],
146 146 full_name: user[2],
147 147 count: user[3],
148 148 min: user[4],
149 149 max: user[5],
150 150 ip: x
151 151 }
152 152 end
153 153 end
154 154
155 155 def login_detail_query
156 156 @logins = Array.new
157 157
158 158 date_and_time = '%Y-%m-%d %H:%M'
159 159 begin
160 160 md = params[:since_datetime].match(/(\d+)-(\d+)-(\d+) (\d+):(\d+)/)
161 161 @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)
162 162 rescue
163 163 @since_time = DateTime.new(1000,1,1)
164 164 end
165 165 begin
166 166 md = params[:until_datetime].match(/(\d+)-(\d+)-(\d+) (\d+):(\d+)/)
167 167 @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)
168 168 rescue
169 169 @until_time = DateTime.new(3000,1,1)
170 170 end
171 171
172 172 @logins = Login.includes(:user).where("logins.created_at >= ? AND logins.created_at <= ?",@since_time, @until_time)
173 173 case params[:users]
174 174 when 'enabled'
175 175 @logins = @logins.where(users: {enabled: true})
176 176 when 'group'
177 177 @logins = @logins.joins(user: :groups).where(user: {groups: {id: params[:groups]}}) if params[:groups]
178 178 end
179 179 end
180 180
181 181 def submission
182 182 end
183 183
184 184 def submission_query
185 185 @submissions = Submission
186 186 .includes(:problem).includes(:user).includes(:language)
187 187
188 188 case params[:users]
189 189 when 'enabled'
190 190 @submissions = @submissions.where(users: {enabled: true})
191 191 when 'group'
192 192 @submissions = @submissions.joins(user: :groups).where(user: {groups: {id: params[:groups]}}) if params[:groups]
193 193 end
194 194
195 195 case params[:problems]
196 196 when 'enabled'
197 197 @submissions = @submissions.where(problems: {available: true})
198 198 when 'selected'
199 199 @submissions = @submissions.where(problem_id: params[:problem_id])
200 200 end
201 201
@@ -264,301 +264,301
264 264 if sub.max_runtime and sub.max_runtime < @by_lang[lang.pretty_name][:runtime][:value]
265 265 @by_lang[lang.pretty_name][:runtime] = { avail: true, user_id: sub.user_id, value: sub.max_runtime, sub_id: sub.id }
266 266 end
267 267
268 268 if sub.peak_memory and sub.peak_memory < @by_lang[lang.pretty_name][:memory][:value]
269 269 @by_lang[lang.pretty_name][:memory] = { avail: true, user_id: sub.user_id, value: sub.peak_memory, sub_id: sub.id }
270 270 end
271 271
272 272 if sub.submitted_at and sub.submitted_at < @by_lang[lang.pretty_name][:first][:value] and sub.user and
273 273 !sub.user.admin?
274 274 @by_lang[lang.pretty_name][:first] = { avail: true, user_id: sub.user_id, value: sub.submitted_at, sub_id: sub.id }
275 275 end
276 276
277 277 if @by_lang[lang.pretty_name][:length][:value] > sub.effective_code_length
278 278 @by_lang[lang.pretty_name][:length] = { avail: true, user_id: sub.user_id, value: sub.effective_code_length, sub_id: sub.id }
279 279 end
280 280 end
281 281
282 282 #process user_id
283 283 @by_lang.each do |lang,prop|
284 284 prop.each do |k,v|
285 285 v[:user] = User.exists?(v[:user_id]) ? User.find(v[:user_id]).full_name : "(NULL)"
286 286 end
287 287 end
288 288
289 289 #sum into best
290 290 if @by_lang and @by_lang.first
291 291 @best = @by_lang.first[1].clone
292 292 @by_lang.each do |lang,prop|
293 293 if @best[:runtime][:value] >= prop[:runtime][:value]
294 294 @best[:runtime] = prop[:runtime]
295 295 @best[:runtime][:lang] = lang
296 296 end
297 297 if @best[:memory][:value] >= prop[:memory][:value]
298 298 @best[:memory] = prop[:memory]
299 299 @best[:memory][:lang] = lang
300 300 end
301 301 if @best[:length][:value] >= prop[:length][:value]
302 302 @best[:length] = prop[:length]
303 303 @best[:length][:lang] = lang
304 304 end
305 305 if @best[:first][:value] >= prop[:first][:value]
306 306 @best[:first] = prop[:first]
307 307 @best[:first][:lang] = lang
308 308 end
309 309 end
310 310 end
311 311
312 312 @histogram[:summary][:max] = [@histogram[:data].max,1].max
313 313 @summary[:attempt] = user.count
314 314 user.each_value { |v| @summary[:solve] += 1 if v == 1 }
315 315 end
316 316
317 317 def stuck #report struggling user,problem
318 318 # init
319 319 user,problem = nil
320 320 solve = true
321 321 tries = 0
322 322 @struggle = Array.new
323 323 record = {}
324 324 Submission.includes(:problem,:user).order(:problem_id,:user_id).find_each do |sub|
325 325 next unless sub.problem and sub.user
326 326 if user != sub.user_id or problem != sub.problem_id
327 327 @struggle << { user: record[:user], problem: record[:problem], tries: tries } unless solve
328 328 record = {user: sub.user, problem: sub.problem}
329 329 user,problem = sub.user_id, sub.problem_id
330 330 solve = false
331 331 tries = 0
332 332 end
333 333 if sub.points >= sub.problem.full_score
334 334 solve = true
335 335 else
336 336 tries += 1
337 337 end
338 338 end
339 339 @struggle.sort!{|a,b| b[:tries] <=> a[:tries] }
340 340 @struggle = @struggle[0..50]
341 341 end
342 342
343 343
344 344 def multiple_login
345 345 #user with multiple IP
346 346 raw = Submission.joins(:user).joins(:problem).where("problems.available != 0").group("login,ip_address").order(:login)
347 347 last,count = 0,0
348 348 first = 0
349 349 @users = []
350 350 raw.each do |r|
351 351 if last != r.user.login
352 352 count = 1
353 353 last = r.user.login
354 354 first = r
355 355 else
356 356 @users << first if count == 1
357 357 @users << r
358 358 count += 1
359 359 end
360 360 end
361 361
362 362 #IP with multiple user
363 363 raw = Submission.joins(:user).joins(:problem).where("problems.available != 0").group("login,ip_address").order(:ip_address)
364 364 last,count = 0,0
365 365 first = 0
366 366 @ip = []
367 367 raw.each do |r|
368 368 if last != r.ip_address
369 369 count = 1
370 370 last = r.ip_address
371 371 first = r
372 372 else
373 373 @ip << first if count == 1
374 374 @ip << r
375 375 count += 1
376 376 end
377 377 end
378 378 end
379 379
380 380 def cheat_report
381 381 date_and_time = '%Y-%m-%d %H:%M'
382 382 begin
383 383 md = params[:since_datetime].match(/(\d+)-(\d+)-(\d+) (\d+):(\d+)/)
384 384 @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)
385 385 rescue
386 386 @since_time = Time.zone.now.ago( 90.minutes)
387 387 end
388 388 begin
389 389 md = params[:until_datetime].match(/(\d+)-(\d+)-(\d+) (\d+):(\d+)/)
390 390 @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)
391 391 rescue
392 392 @until_time = Time.zone.now
393 393 end
394 394
395 395 #multi login
396 396 @ml = Login.joins(:user).where("logins.created_at >= ? and logins.created_at <= ?",@since_time,@until_time).select('users.login,count(distinct ip_address) as count,users.full_name').group("users.id").having("count > 1")
397 397
398 398 st = <<-SQL
399 399 SELECT l2.*
400 400 FROM logins l2 INNER JOIN
401 401 (SELECT u.id,COUNT(DISTINCT ip_address) as count,u.login,u.full_name
402 402 FROM logins l
403 403 INNER JOIN users u ON l.user_id = u.id
404 404 WHERE l.created_at >= '#{@since_time.in_time_zone("UTC")}' and l.created_at <= '#{@until_time.in_time_zone("UTC")}'
405 405 GROUP BY u.id
406 406 HAVING count > 1
407 407 ) ml ON l2.user_id = ml.id
408 408 WHERE l2.created_at >= '#{@since_time.in_time_zone("UTC")}' and l2.created_at <= '#{@until_time.in_time_zone("UTC")}'
409 409 UNION
410 410 SELECT l2.*
411 411 FROM logins l2 INNER JOIN
412 412 (SELECT l.ip_address,COUNT(DISTINCT u.id) as count
413 413 FROM logins l
414 414 INNER JOIN users u ON l.user_id = u.id
415 415 WHERE l.created_at >= '#{@since_time.in_time_zone("UTC")}' and l.created_at <= '#{@until_time.in_time_zone("UTC")}'
416 416 GROUP BY l.ip_address
417 417 HAVING count > 1
418 418 ) ml on ml.ip_address = l2.ip_address
419 419 INNER JOIN users u ON l2.user_id = u.id
420 420 WHERE l2.created_at >= '#{@since_time.in_time_zone("UTC")}' and l2.created_at <= '#{@until_time.in_time_zone("UTC")}'
421 421 ORDER BY ip_address,created_at
422 422 SQL
423 423 @mld = Login.find_by_sql(st)
424 424
425 425 st = <<-SQL
426 426 SELECT s.id,s.user_id,s.ip_address,s.submitted_at,s.problem_id
427 427 FROM submissions s INNER JOIN
428 428 (SELECT u.id,COUNT(DISTINCT ip_address) as count,u.login,u.full_name
429 429 FROM logins l
430 430 INNER JOIN users u ON l.user_id = u.id
431 431 WHERE l.created_at >= ? and l.created_at <= ?
432 432 GROUP BY u.id
433 433 HAVING count > 1
434 434 ) ml ON s.user_id = ml.id
435 435 WHERE s.submitted_at >= ? and s.submitted_at <= ?
436 436 UNION
437 437 SELECT s.id,s.user_id,s.ip_address,s.submitted_at,s.problem_id
438 438 FROM submissions s INNER JOIN
439 439 (SELECT l.ip_address,COUNT(DISTINCT u.id) as count
440 440 FROM logins l
441 441 INNER JOIN users u ON l.user_id = u.id
442 442 WHERE l.created_at >= ? and l.created_at <= ?
443 443 GROUP BY l.ip_address
444 444 HAVING count > 1
445 445 ) ml on ml.ip_address = s.ip_address
446 446 WHERE s.submitted_at >= ? and s.submitted_at <= ?
447 447 ORDER BY ip_address,submitted_at
448 448 SQL
449 449 @subs = Submission.joins(:problem).find_by_sql([st,@since_time,@until_time,
450 450 @since_time,@until_time,
451 451 @since_time,@until_time,
452 452 @since_time,@until_time])
453 453
454 454 end
455 455
456 - def cheat_scruntinize
456 + def cheat_scrutinize
457 457 #convert date & time
458 458 date_and_time = '%Y-%m-%d %H:%M'
459 459 begin
460 460 md = params[:since_datetime].match(/(\d+)-(\d+)-(\d+) (\d+):(\d+)/)
461 461 @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)
462 462 rescue
463 463 @since_time = Time.zone.now.ago( 90.minutes)
464 464 end
465 465 begin
466 466 md = params[:until_datetime].match(/(\d+)-(\d+)-(\d+) (\d+):(\d+)/)
467 467 @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)
468 468 rescue
469 469 @until_time = Time.zone.now
470 470 end
471 471
472 472 #convert sid
473 473 @sid = params[:SID].split(/[,\s]/) if params[:SID]
474 474 unless @sid and @sid.size > 0
475 475 return
476 - redirect_to actoin: :cheat_scruntinize
476 + redirect_to actoin: :cheat_scrutinize
477 477 flash[:notice] = 'Please enter at least 1 student id'
478 478 end
479 479 mark = Array.new(@sid.size,'?')
480 480 condition = "(u.login = " + mark.join(' OR u.login = ') + ')'
481 481
482 482 @st = <<-SQL
483 483 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
484 484 FROM logins l INNER JOIN users u on l.user_id = u.id
485 485 WHERE l.created_at >= ? AND l.created_at <= ? AND #{condition}
486 486 UNION
487 487 SELECT s.submitted_at,s.id,u.login,u.full_name,s.ip_address,s.problem_id,s.points,s.user_id
488 488 FROM submissions s INNER JOIN users u ON s.user_id = u.id
489 489 WHERE s.submitted_at >= ? AND s.submitted_at <= ? AND #{condition}
490 490 ORDER BY submitted_at
491 491 SQL
492 492
493 493 p = [@st,@since_time,@until_time] + @sid + [@since_time,@until_time] + @sid
494 494 @logs = Submission.joins(:problem).find_by_sql(p)
495 495
496 496
497 497
498 498
499 499
500 500 end
501 501
502 502 protected
503 503
504 504 def calculate_max_score(problems, users,since_id,until_id, get_last_score = false)
505 505 #scorearray[i] = user #i's user stat where i is the index (not id)
506 506 scorearray = Array.new
507 507 users.each do |u|
508 508 ustat = Array.new
509 509 ustat[0] = u
510 510 problems.each do |p|
511 511 unless get_last_score
512 512 #get max score
513 513 max_points = 0
514 514 Submission.find_in_range_by_user_and_problem(u.id,p.id,since_id,until_id).each do |sub|
515 515 max_points = sub.points if sub and sub.points and (sub.points > max_points)
516 516 end
517 517 ustat << [(max_points.to_f*100/p.full_score).round, (max_points>=p.full_score)]
518 518 else
519 519 #get latest score
520 520 sub = Submission.find_last_by_user_and_problem(u.id,p.id)
521 521 if (sub!=nil) and (sub.points!=nil) and p and p.full_score
522 522 ustat << [(sub.points.to_f*100/p.full_score).round, (sub.points>=p.full_score)]
523 523 else
524 524 ustat << [0,false]
525 525 end
526 526 end
527 527 end
528 528 scorearray << ustat
529 529 end
530 530 return scorearray
531 531 end
532 532
533 533 def gen_csv_from_scorearray(scorearray,problem)
534 534 CSV.generate do |csv|
535 535 #add header
536 536 header = ['User','Name', 'Activated?', 'Logged in', 'Contest']
537 537 problem.each { |p| header << p.name }
538 538 header += ['Total','Passed']
539 539 csv << header
540 540 #add data
541 541 scorearray.each do |sc|
542 542 total = num_passed = 0
543 543 row = Array.new
544 544 sc.each_index do |i|
545 545 if i == 0
546 546 row << sc[i].login
547 547 row << sc[i].full_name
548 548 row << sc[i].activated
549 549 row << (sc[i].try(:contest_stat).try(:started_at)!=nil ? 'yes' : 'no')
550 550 row << sc[i].contests.collect {|c| c.name}.join(', ')
551 551 else
552 552 row << sc[i][0]
553 553 total += sc[i][0]
554 554 num_passed += 1 if sc[i][1]
555 555 end
556 556 end
557 557 row << total
558 558 row << num_passed
559 559 csv << row
560 560 end
561 561 end
562 562 end
563 563
564 564 end
@@ -1,211 +1,211
1 1 Rails.application.routes.draw do
2 2 resources :tags
3 3 get "sources/direct_edit"
4 4
5 5 root :to => 'main#login'
6 6
7 7 #logins
8 8 match 'login/login', to: 'login#login', via: [:get,:post]
9 9
10 10 resources :contests
11 11 resources :sites
12 12 resources :test
13 13
14 14 resources :messages do
15 15 member do
16 16 get 'hide'
17 17 post 'reply'
18 18 end
19 19 collection do
20 20 get 'console'
21 21 get 'list_all'
22 22 end
23 23 end
24 24
25 25 resources :announcements do
26 26 member do
27 27 get 'toggle','toggle_front'
28 28 end
29 29 end
30 30
31 31 resources :problems do
32 32 member do
33 33 get 'toggle'
34 34 get 'toggle_test'
35 35 get 'toggle_view_testcase'
36 36 get 'stat'
37 37 end
38 38 collection do
39 39 get 'turn_all_off'
40 40 get 'turn_all_on'
41 41 get 'import'
42 42 get 'manage'
43 43 get 'quick_create'
44 44 post 'do_manage'
45 45 post 'do_import'
46 46 end
47 47 end
48 48
49 49 resources :groups do
50 50 member do
51 51 post 'add_user', to: 'groups#add_user', as: 'add_user'
52 52 delete 'remove_user/:user_id', to: 'groups#remove_user', as: 'remove_user'
53 53 delete 'remove_all_user', to: 'groups#remove_all_user', as: 'remove_all_user'
54 54 post 'add_problem', to: 'groups#add_problem', as: 'add_problem'
55 55 delete 'remove_problem/:problem_id', to: 'groups#remove_problem', as: 'remove_problem'
56 56 delete 'remove_all_problem', to: 'groups#remove_all_problem', as: 'remove_all_problem'
57 57 end
58 58 collection do
59 59
60 60 end
61 61 end
62 62
63 63 resources :testcases, only: [] do
64 64 member do
65 65 get 'download_input'
66 66 get 'download_sol'
67 67 end
68 68 collection do
69 69 get 'show_problem/:problem_id(/:test_num)' => 'testcases#show_problem', as: 'show_problem'
70 70 end
71 71 end
72 72
73 73 resources :grader_configuration, controller: 'configurations' do
74 74 collection do
75 75 get 'set_exam_right(/:value)', action: 'set_exam_right', as: 'set_exam_right'
76 76 end
77 77 end
78 78
79 79 resources :users do
80 80 member do
81 81 get 'toggle_activate', 'toggle_enable'
82 82 get 'stat'
83 83 end
84 84 collection do
85 85 get 'profile'
86 86 post 'chg_passwd'
87 87 end
88 88 end
89 89
90 90 resources :submissions do
91 91 member do
92 92 get 'download'
93 93 get 'compiler_msg'
94 94 get 'rejudge'
95 95 get 'source'
96 96 end
97 97 collection do
98 98 get 'prob/:problem_id', to: 'submissions#index', as: 'problem'
99 99 get 'direct_edit_problem/:problem_id(/:user_id)', to: 'submissions#direct_edit_problem', as: 'direct_edit_problem'
100 100 get 'get_latest_submission_status/:uid/:pid', to: 'submissions#get_latest_submission_status', as: 'get_latest_submission_status'
101 101 end
102 102 end
103 103
104 104
105 105 #user admin
106 106 resources :user_admin do
107 107 collection do
108 108 match 'bulk_manage', via: [:get, :post]
109 109 get 'bulk_mail'
110 110 get 'user_stat'
111 111 get 'import'
112 112 get 'new_list'
113 113 get 'admin'
114 114 get 'active'
115 115 get 'mass_mailing'
116 116 get 'revoke_admin'
117 117 post 'grant_admin'
118 118 match 'create_from_list', via: [:get, :post]
119 119 match 'random_all_passwords', via: [:get, :post]
120 120 end
121 121 member do
122 122 get 'clear_last_ip'
123 123 end
124 124 end
125 125
126 126 resources :contest_management, only: [:index] do
127 127 collection do
128 128 get 'user_stat'
129 129 get 'clear_stat'
130 130 get 'clear_all_stat'
131 131 get 'change_contest_mode'
132 132 end
133 133 end
134 134
135 135 #get 'user_admin', to: 'user_admin#index'
136 136 #get 'user_admin/bulk_manage', to: 'user_admin#bulk_manage', as: 'bulk_manage_user_admin'
137 137 #post 'user_admin', to: 'user_admin#create'
138 138 #delete 'user_admin/:id', to: 'user_admin#destroy', as: 'user_admin_destroy'
139 139
140 140 #singular resource
141 141 #---- BEWARE ---- singular resource maps to plural controller by default, we can override by provide controller name directly
142 142 #report
143 143 resource :report, only: [], controller: 'report' do
144 144 get 'login'
145 145 get 'multiple_login'
146 146 get 'problem_hof(/:id)', action: 'problem_hof', as: 'problem_hof'
147 147 get 'current_score(/:group_id)', action: 'current_score', as: 'current_score'
148 148 get 'max_score'
149 149 post 'show_max_score'
150 150 get 'stuck'
151 151 get 'cheat_report'
152 152 post 'cheat_report'
153 - get 'cheat_scruntinize'
154 - post 'cheat_scruntinize'
153 + get 'cheat_scrutinize'
154 + post 'cheat_scrutinize'
155 155 get 'submission'
156 156 post 'submission_query'
157 157 get 'login_stat'
158 158 post 'login_stat'
159 159 get 'login'
160 160 post 'login_summary_query'
161 161 post 'login_detail_query'
162 162 end
163 163 #get 'report/current_score', to: 'report#current_score', as: 'report_current_score'
164 164 #get 'report/problem_hof(/:id)', to: 'report#problem_hof', as: 'report_problem_hof'
165 165 #get "report/login"
166 166 #get 'report/max_score', to: 'report#max_score', as: 'report_max_score'
167 167 #post 'report/show_max_score', to: 'report#show_max_score', as: 'report_show_max_score'
168 168
169 169 resource :main, only: [], controller: 'main' do
170 170 get 'login'
171 171 get 'logout'
172 172 get 'list'
173 173 get 'submission(/:id)', action: 'submission', as: 'main_submission'
174 174 get 'announcements'
175 175 get 'help'
176 176 post 'submit'
177 177 end
178 178 #main
179 179 #get "main/list"
180 180 #get 'main/submission(/:id)', to: 'main#submission', as: 'main_submission'
181 181 #post 'main/submit', to: 'main#submit'
182 182 #get 'main/announcements', to: 'main#announcements'
183 183
184 184
185 185 #
186 186 get 'tasks/view/:file.:ext' => 'tasks#view'
187 187 get 'tasks/download/:id/:file.:ext' => 'tasks#download'
188 188 get 'heartbeat/:id/edit' => 'heartbeat#edit'
189 189
190 190 #grader
191 191 get 'graders/list', to: 'graders#list', as: 'grader_list'
192 192 namespace :graders do
193 193 get 'task/:id/:type', action: 'task', as: 'task'
194 194 get 'view/:id/:type', action: 'view', as: 'view'
195 195 get 'clear/:id', action: 'clear', as: 'clear'
196 196 get 'stop'
197 197 get 'stop_all'
198 198 get 'clear_all'
199 199 get 'clear_terminated'
200 200 get 'start_grading'
201 201 get 'start_exam'
202 202
203 203 end
204 204
205 205
206 206 # See how all your routes lay out with "rake routes"
207 207
208 208 # This is a legacy wild controller route that's not recommended for RESTful applications.
209 209 # Note: This route will make all actions in every controller accessible via GET requests.
210 210 # match ':controller(/:action(/:id))(.:format)', via: [:get, :post]
211 211 end
deleted file
You need to be logged in to leave comments. Login now