Description:
- fix syntax error
Commit status:
[Not Reviewed]
References:
Comments:
0 Commit comments 0 Inline Comments
Unresolved TODOs:
There are no unresolved TODOs
Add another comment

r599:14a14eb28fed - - 1 file changed: 1 inserted, 0 deleted

@@ -95,390 +95,391
95 end
95 end
96
96
97 def login_stat
97 def login_stat
98 @logins = Array.new
98 @logins = Array.new
99
99
100 date_and_time = '%Y-%m-%d %H:%M'
100 date_and_time = '%Y-%m-%d %H:%M'
101 begin
101 begin
102 md = params[:since_datetime].match(/(\d+)-(\d+)-(\d+) (\d+):(\d+)/)
102 md = params[:since_datetime].match(/(\d+)-(\d+)-(\d+) (\d+):(\d+)/)
103 @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)
103 @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)
104 rescue
104 rescue
105 @since_time = DateTime.new(1000,1,1)
105 @since_time = DateTime.new(1000,1,1)
106 end
106 end
107 begin
107 begin
108 md = params[:until_datetime].match(/(\d+)-(\d+)-(\d+) (\d+):(\d+)/)
108 md = params[:until_datetime].match(/(\d+)-(\d+)-(\d+) (\d+):(\d+)/)
109 @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)
109 @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)
110 rescue
110 rescue
111 @until_time = DateTime.new(3000,1,1)
111 @until_time = DateTime.new(3000,1,1)
112 end
112 end
113
113
114 User.all.each do |user|
114 User.all.each do |user|
115 @logins << { id: user.id,
115 @logins << { id: user.id,
116 login: user.login,
116 login: user.login,
117 full_name: user.full_name,
117 full_name: user.full_name,
118 count: Login.where("user_id = ? AND created_at >= ? AND created_at <= ?",
118 count: Login.where("user_id = ? AND created_at >= ? AND created_at <= ?",
119 user.id,@since_time,@until_time)
119 user.id,@since_time,@until_time)
120 .count(:id),
120 .count(:id),
121 min: Login.where("user_id = ? AND created_at >= ? AND created_at <= ?",
121 min: Login.where("user_id = ? AND created_at >= ? AND created_at <= ?",
122 user.id,@since_time,@until_time)
122 user.id,@since_time,@until_time)
123 .minimum(:created_at),
123 .minimum(:created_at),
124 max: Login.where("user_id = ? AND created_at >= ? AND created_at <= ?",
124 max: Login.where("user_id = ? AND created_at >= ? AND created_at <= ?",
125 user.id,@since_time,@until_time)
125 user.id,@since_time,@until_time)
126 .maximum(:created_at),
126 .maximum(:created_at),
127 ip: Login.where("user_id = ? AND created_at >= ? AND created_at <= ?",
127 ip: Login.where("user_id = ? AND created_at >= ? AND created_at <= ?",
128 user.id,@since_time,@until_time)
128 user.id,@since_time,@until_time)
129 .select(:ip_address).uniq
129 .select(:ip_address).uniq
130
130
131 }
131 }
132 end
132 end
133 end
133 end
134
134
135 def submission_stat
135 def submission_stat
136
136
137 date_and_time = '%Y-%m-%d %H:%M'
137 date_and_time = '%Y-%m-%d %H:%M'
138 begin
138 begin
139 @since_time = DateTime.strptime(params[:since_datetime],date_and_time)
139 @since_time = DateTime.strptime(params[:since_datetime],date_and_time)
140 rescue
140 rescue
141 @since_time = DateTime.new(1000,1,1)
141 @since_time = DateTime.new(1000,1,1)
142 end
142 end
143 begin
143 begin
144 @until_time = DateTime.strptime(params[:until_datetime],date_and_time)
144 @until_time = DateTime.strptime(params[:until_datetime],date_and_time)
145 rescue
145 rescue
146 @until_time = DateTime.new(3000,1,1)
146 @until_time = DateTime.new(3000,1,1)
147 end
147 end
148
148
149 @submissions = {}
149 @submissions = {}
150
150
151 User.find_each do |user|
151 User.find_each do |user|
152 @submissions[user.id] = { login: user.login, full_name: user.full_name, count: 0, sub: { } }
152 @submissions[user.id] = { login: user.login, full_name: user.full_name, count: 0, sub: { } }
153 end
153 end
154
154
155 Submission.where("submitted_at >= ? AND submitted_at <= ?",@since_time,@until_time).find_each do |s|
155 Submission.where("submitted_at >= ? AND submitted_at <= ?",@since_time,@until_time).find_each do |s|
156 if @submissions[s.user_id]
156 if @submissions[s.user_id]
157 if not @submissions[s.user_id][:sub].has_key?(s.problem_id)
157 if not @submissions[s.user_id][:sub].has_key?(s.problem_id)
158 a = Problem.find_by_id(s.problem_id)
158 a = Problem.find_by_id(s.problem_id)
159 @submissions[s.user_id][:sub][s.problem_id] =
159 @submissions[s.user_id][:sub][s.problem_id] =
160 { prob_name: (a ? a.full_name : '(NULL)'),
160 { prob_name: (a ? a.full_name : '(NULL)'),
161 sub_ids: [s.id] }
161 sub_ids: [s.id] }
162 else
162 else
163 @submissions[s.user_id][:sub][s.problem_id][:sub_ids] << s.id
163 @submissions[s.user_id][:sub][s.problem_id][:sub_ids] << s.id
164 end
164 end
165 @submissions[s.user_id][:count] += 1
165 @submissions[s.user_id][:count] += 1
166 end
166 end
167 end
167 end
168 end
168 end
169
169
170 def problem_hof
170 def problem_hof
171 # gen problem list
171 # gen problem list
172 @user = User.find(session[:user_id])
172 @user = User.find(session[:user_id])
173 @problems = @user.available_problems
173 @problems = @user.available_problems
174
174
175 # get selected problems or the default
175 # get selected problems or the default
176 if params[:id]
176 if params[:id]
177 begin
177 begin
178 @problem = Problem.available.find(params[:id])
178 @problem = Problem.available.find(params[:id])
179 rescue
179 rescue
180 redirect_to action: :problem_hof
180 redirect_to action: :problem_hof
181 flash[:notice] = 'Error: submissions for that problem are not viewable.'
181 flash[:notice] = 'Error: submissions for that problem are not viewable.'
182 return
182 return
183 end
183 end
184 end
184 end
185
185
186 return unless @problem
186 return unless @problem
187
187
188 @by_lang = {} #aggregrate by language
188 @by_lang = {} #aggregrate by language
189
189
190 range =65
190 range =65
191 @histogram = { data: Array.new(range,0), summary: {} }
191 @histogram = { data: Array.new(range,0), summary: {} }
192 @summary = {count: 0, solve: 0, attempt: 0}
192 @summary = {count: 0, solve: 0, attempt: 0}
193 user = Hash.new(0)
193 user = Hash.new(0)
194 Submission.where(problem_id: @problem.id).find_each do |sub|
194 Submission.where(problem_id: @problem.id).find_each do |sub|
195 #histogram
195 #histogram
196 d = (DateTime.now.in_time_zone - sub.submitted_at) / 24 / 60 / 60
196 d = (DateTime.now.in_time_zone - sub.submitted_at) / 24 / 60 / 60
197 @histogram[:data][d.to_i] += 1 if d < range
197 @histogram[:data][d.to_i] += 1 if d < range
198
198
199 next unless sub.points
199 next unless sub.points
200 @summary[:count] += 1
200 @summary[:count] += 1
201 user[sub.user_id] = [user[sub.user_id], (sub.points >= @problem.full_score) ? 1 : 0].max
201 user[sub.user_id] = [user[sub.user_id], (sub.points >= @problem.full_score) ? 1 : 0].max
202
202
203 lang = Language.find_by_id(sub.language_id)
203 lang = Language.find_by_id(sub.language_id)
204 next unless lang
204 next unless lang
205 next unless sub.points >= @problem.full_score
205 next unless sub.points >= @problem.full_score
206
206
207 #initialize
207 #initialize
208 unless @by_lang.has_key?(lang.pretty_name)
208 unless @by_lang.has_key?(lang.pretty_name)
209 @by_lang[lang.pretty_name] = {
209 @by_lang[lang.pretty_name] = {
210 runtime: { avail: false, value: 2**30-1 },
210 runtime: { avail: false, value: 2**30-1 },
211 memory: { avail: false, value: 2**30-1 },
211 memory: { avail: false, value: 2**30-1 },
212 length: { avail: false, value: 2**30-1 },
212 length: { avail: false, value: 2**30-1 },
213 first: { avail: false, value: DateTime.new(3000,1,1) }
213 first: { avail: false, value: DateTime.new(3000,1,1) }
214 }
214 }
215 end
215 end
216
216
217 if sub.max_runtime and sub.max_runtime < @by_lang[lang.pretty_name][:runtime][:value]
217 if sub.max_runtime and sub.max_runtime < @by_lang[lang.pretty_name][:runtime][:value]
218 @by_lang[lang.pretty_name][:runtime] = { avail: true, user_id: sub.user_id, value: sub.max_runtime, sub_id: sub.id }
218 @by_lang[lang.pretty_name][:runtime] = { avail: true, user_id: sub.user_id, value: sub.max_runtime, sub_id: sub.id }
219 end
219 end
220
220
221 if sub.peak_memory and sub.peak_memory < @by_lang[lang.pretty_name][:memory][:value]
221 if sub.peak_memory and sub.peak_memory < @by_lang[lang.pretty_name][:memory][:value]
222 @by_lang[lang.pretty_name][:memory] = { avail: true, user_id: sub.user_id, value: sub.peak_memory, sub_id: sub.id }
222 @by_lang[lang.pretty_name][:memory] = { avail: true, user_id: sub.user_id, value: sub.peak_memory, sub_id: sub.id }
223 end
223 end
224
224
225 if sub.submitted_at and sub.submitted_at < @by_lang[lang.pretty_name][:first][:value] and
225 if sub.submitted_at and sub.submitted_at < @by_lang[lang.pretty_name][:first][:value] and
226 !sub.user.admin?
226 !sub.user.admin?
227 @by_lang[lang.pretty_name][:first] = { avail: true, user_id: sub.user_id, value: sub.submitted_at, sub_id: sub.id }
227 @by_lang[lang.pretty_name][:first] = { avail: true, user_id: sub.user_id, value: sub.submitted_at, sub_id: sub.id }
228 end
228 end
229
229
230 if @by_lang[lang.pretty_name][:length][:value] > sub.effective_code_length
230 if @by_lang[lang.pretty_name][:length][:value] > sub.effective_code_length
231 @by_lang[lang.pretty_name][:length] = { avail: true, user_id: sub.user_id, value: sub.effective_code_length, sub_id: sub.id }
231 @by_lang[lang.pretty_name][:length] = { avail: true, user_id: sub.user_id, value: sub.effective_code_length, sub_id: sub.id }
232 end
232 end
233 end
233 end
234
234
235 #process user_id
235 #process user_id
236 @by_lang.each do |lang,prop|
236 @by_lang.each do |lang,prop|
237 prop.each do |k,v|
237 prop.each do |k,v|
238 v[:user] = User.exists?(v[:user_id]) ? User.find(v[:user_id]).full_name : "(NULL)"
238 v[:user] = User.exists?(v[:user_id]) ? User.find(v[:user_id]).full_name : "(NULL)"
239 end
239 end
240 end
240 end
241
241
242 #sum into best
242 #sum into best
243 if @by_lang and @by_lang.first
243 if @by_lang and @by_lang.first
244 @best = @by_lang.first[1].clone
244 @best = @by_lang.first[1].clone
245 @by_lang.each do |lang,prop|
245 @by_lang.each do |lang,prop|
246 if @best[:runtime][:value] >= prop[:runtime][:value]
246 if @best[:runtime][:value] >= prop[:runtime][:value]
247 @best[:runtime] = prop[:runtime]
247 @best[:runtime] = prop[:runtime]
248 @best[:runtime][:lang] = lang
248 @best[:runtime][:lang] = lang
249 end
249 end
250 if @best[:memory][:value] >= prop[:memory][:value]
250 if @best[:memory][:value] >= prop[:memory][:value]
251 @best[:memory] = prop[:memory]
251 @best[:memory] = prop[:memory]
252 @best[:memory][:lang] = lang
252 @best[:memory][:lang] = lang
253 end
253 end
254 if @best[:length][:value] >= prop[:length][:value]
254 if @best[:length][:value] >= prop[:length][:value]
255 @best[:length] = prop[:length]
255 @best[:length] = prop[:length]
256 @best[:length][:lang] = lang
256 @best[:length][:lang] = lang
257 end
257 end
258 if @best[:first][:value] >= prop[:first][:value]
258 if @best[:first][:value] >= prop[:first][:value]
259 @best[:first] = prop[:first]
259 @best[:first] = prop[:first]
260 @best[:first][:lang] = lang
260 @best[:first][:lang] = lang
261 end
261 end
262 end
262 end
263 end
263 end
264
264
265 @histogram[:summary][:max] = [@histogram[:data].max,1].max
265 @histogram[:summary][:max] = [@histogram[:data].max,1].max
266 @summary[:attempt] = user.count
266 @summary[:attempt] = user.count
267 user.each_value { |v| @summary[:solve] += 1 if v == 1 }
267 user.each_value { |v| @summary[:solve] += 1 if v == 1 }
268 end
268 end
269
269
270 def stuck #report struggling user,problem
270 def stuck #report struggling user,problem
271 # init
271 # init
272 user,problem = nil
272 user,problem = nil
273 solve = true
273 solve = true
274 tries = 0
274 tries = 0
275 @struggle = Array.new
275 @struggle = Array.new
276 record = {}
276 record = {}
277 Submission.includes(:problem,:user).order(:problem_id,:user_id).find_each do |sub|
277 Submission.includes(:problem,:user).order(:problem_id,:user_id).find_each do |sub|
278 next unless sub.problem and sub.user
278 next unless sub.problem and sub.user
279 if user != sub.user_id or problem != sub.problem_id
279 if user != sub.user_id or problem != sub.problem_id
280 @struggle << { user: record[:user], problem: record[:problem], tries: tries } unless solve
280 @struggle << { user: record[:user], problem: record[:problem], tries: tries } unless solve
281 record = {user: sub.user, problem: sub.problem}
281 record = {user: sub.user, problem: sub.problem}
282 user,problem = sub.user_id, sub.problem_id
282 user,problem = sub.user_id, sub.problem_id
283 solve = false
283 solve = false
284 tries = 0
284 tries = 0
285 end
285 end
286 if sub.points >= sub.problem.full_score
286 if sub.points >= sub.problem.full_score
287 solve = true
287 solve = true
288 else
288 else
289 tries += 1
289 tries += 1
290 end
290 end
291 end
291 end
292 @struggle.sort!{|a,b| b[:tries] <=> a[:tries] }
292 @struggle.sort!{|a,b| b[:tries] <=> a[:tries] }
293 @struggle = @struggle[0..50]
293 @struggle = @struggle[0..50]
294 end
294 end
295
295
296
296
297 def multiple_login
297 def multiple_login
298 #user with multiple IP
298 #user with multiple IP
299 raw = Submission.joins(:user).joins(:problem).where("problems.available != 0").group("login,ip_address").order(:login)
299 raw = Submission.joins(:user).joins(:problem).where("problems.available != 0").group("login,ip_address").order(:login)
300 last,count = 0,0
300 last,count = 0,0
301 first = 0
301 first = 0
302 @users = []
302 @users = []
303 raw.each do |r|
303 raw.each do |r|
304 if last != r.user.login
304 if last != r.user.login
305 count = 1
305 count = 1
306 last = r.user.login
306 last = r.user.login
307 first = r
307 first = r
308 else
308 else
309 @users << first if count == 1
309 @users << first if count == 1
310 @users << r
310 @users << r
311 count += 1
311 count += 1
312 end
312 end
313 end
313 end
314
314
315 #IP with multiple user
315 #IP with multiple user
316 raw = Submission.joins(:user).joins(:problem).where("problems.available != 0").group("login,ip_address").order(:ip_address)
316 raw = Submission.joins(:user).joins(:problem).where("problems.available != 0").group("login,ip_address").order(:ip_address)
317 last,count = 0,0
317 last,count = 0,0
318 first = 0
318 first = 0
319 @ip = []
319 @ip = []
320 raw.each do |r|
320 raw.each do |r|
321 if last != r.ip_address
321 if last != r.ip_address
322 count = 1
322 count = 1
323 last = r.ip_address
323 last = r.ip_address
324 first = r
324 first = r
325 else
325 else
326 @ip << first if count == 1
326 @ip << first if count == 1
327 @ip << r
327 @ip << r
328 count += 1
328 count += 1
329 end
329 end
330 end
330 end
331 end
331 end
332
332
333 def cheat_report
333 def cheat_report
334 date_and_time = '%Y-%m-%d %H:%M'
334 date_and_time = '%Y-%m-%d %H:%M'
335 begin
335 begin
336 md = params[:since_datetime].match(/(\d+)-(\d+)-(\d+) (\d+):(\d+)/)
336 md = params[:since_datetime].match(/(\d+)-(\d+)-(\d+) (\d+):(\d+)/)
337 @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)
337 @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)
338 rescue
338 rescue
339 @since_time = Time.zone.now.ago( 90.minutes)
339 @since_time = Time.zone.now.ago( 90.minutes)
340 end
340 end
341 begin
341 begin
342 md = params[:until_datetime].match(/(\d+)-(\d+)-(\d+) (\d+):(\d+)/)
342 md = params[:until_datetime].match(/(\d+)-(\d+)-(\d+) (\d+):(\d+)/)
343 @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)
343 @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)
344 rescue
344 rescue
345 @until_time = Time.zone.now
345 @until_time = Time.zone.now
346 end
346 end
347
347
348 #multi login
348 #multi login
349 @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")
349 @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")
350
350
351 st = <<-SQL
351 st = <<-SQL
352 SELECT l2.*
352 SELECT l2.*
353 FROM logins l2 INNER JOIN
353 FROM logins l2 INNER JOIN
354 (SELECT u.id,COUNT(DISTINCT ip_address) as count,u.login,u.full_name
354 (SELECT u.id,COUNT(DISTINCT ip_address) as count,u.login,u.full_name
355 FROM logins l
355 FROM logins l
356 INNER JOIN users u ON l.user_id = u.id
356 INNER JOIN users u ON l.user_id = u.id
357 WHERE l.created_at >= '#{@since_time.in_time_zone("UTC")}' and l.created_at <= '#{@until_time.in_time_zone("UTC")}'
357 WHERE l.created_at >= '#{@since_time.in_time_zone("UTC")}' and l.created_at <= '#{@until_time.in_time_zone("UTC")}'
358 GROUP BY u.id
358 GROUP BY u.id
359 HAVING count > 1
359 HAVING count > 1
360 ) ml ON l2.user_id = ml.id
360 ) ml ON l2.user_id = ml.id
361 WHERE l2.created_at >= '#{@since_time.in_time_zone("UTC")}' and l2.created_at <= '#{@until_time.in_time_zone("UTC")}'
361 WHERE l2.created_at >= '#{@since_time.in_time_zone("UTC")}' and l2.created_at <= '#{@until_time.in_time_zone("UTC")}'
362 UNION
362 UNION
363 SELECT l2.*
363 SELECT l2.*
364 FROM logins l2 INNER JOIN
364 FROM logins l2 INNER JOIN
365 (SELECT l.ip_address,COUNT(DISTINCT u.id) as count
365 (SELECT l.ip_address,COUNT(DISTINCT u.id) as count
366 FROM logins l
366 FROM logins l
367 INNER JOIN users u ON l.user_id = u.id
367 INNER JOIN users u ON l.user_id = u.id
368 WHERE l.created_at >= '#{@since_time.in_time_zone("UTC")}' and l.created_at <= '#{@until_time.in_time_zone("UTC")}'
368 WHERE l.created_at >= '#{@since_time.in_time_zone("UTC")}' and l.created_at <= '#{@until_time.in_time_zone("UTC")}'
369 GROUP BY l.ip_address
369 GROUP BY l.ip_address
370 HAVING count > 1
370 HAVING count > 1
371 ) ml on ml.ip_address = l2.ip_address
371 ) ml on ml.ip_address = l2.ip_address
372 INNER JOIN users u ON l2.user_id = u.id
372 INNER JOIN users u ON l2.user_id = u.id
373 WHERE l2.created_at >= '#{@since_time.in_time_zone("UTC")}' and l2.created_at <= '#{@until_time.in_time_zone("UTC")}'
373 WHERE l2.created_at >= '#{@since_time.in_time_zone("UTC")}' and l2.created_at <= '#{@until_time.in_time_zone("UTC")}'
374 ORDER BY ip_address,created_at
374 ORDER BY ip_address,created_at
375 SQL
375 SQL
376 @mld = Login.find_by_sql(st)
376 @mld = Login.find_by_sql(st)
377
377
378 st = <<-SQL
378 st = <<-SQL
379 SELECT s.id,s.user_id,s.ip_address,s.submitted_at,s.problem_id
379 SELECT s.id,s.user_id,s.ip_address,s.submitted_at,s.problem_id
380 FROM submissions s INNER JOIN
380 FROM submissions s INNER JOIN
381 (SELECT u.id,COUNT(DISTINCT ip_address) as count,u.login,u.full_name
381 (SELECT u.id,COUNT(DISTINCT ip_address) as count,u.login,u.full_name
382 FROM logins l
382 FROM logins l
383 INNER JOIN users u ON l.user_id = u.id
383 INNER JOIN users u ON l.user_id = u.id
384 WHERE l.created_at >= ? and l.created_at <= ?
384 WHERE l.created_at >= ? and l.created_at <= ?
385 GROUP BY u.id
385 GROUP BY u.id
386 HAVING count > 1
386 HAVING count > 1
387 ) ml ON s.user_id = ml.id
387 ) ml ON s.user_id = ml.id
388 WHERE s.submitted_at >= ? and s.submitted_at <= ?
388 WHERE s.submitted_at >= ? and s.submitted_at <= ?
389 UNION
389 UNION
390 SELECT s.id,s.user_id,s.ip_address,s.submitted_at,s.problem_id
390 SELECT s.id,s.user_id,s.ip_address,s.submitted_at,s.problem_id
391 FROM submissions s INNER JOIN
391 FROM submissions s INNER JOIN
392 (SELECT l.ip_address,COUNT(DISTINCT u.id) as count
392 (SELECT l.ip_address,COUNT(DISTINCT u.id) as count
393 FROM logins l
393 FROM logins l
394 INNER JOIN users u ON l.user_id = u.id
394 INNER JOIN users u ON l.user_id = u.id
395 WHERE l.created_at >= ? and l.created_at <= ?
395 WHERE l.created_at >= ? and l.created_at <= ?
396 GROUP BY l.ip_address
396 GROUP BY l.ip_address
397 HAVING count > 1
397 HAVING count > 1
398 ) ml on ml.ip_address = s.ip_address
398 ) ml on ml.ip_address = s.ip_address
399 WHERE s.submitted_at >= ? and s.submitted_at <= ?
399 WHERE s.submitted_at >= ? and s.submitted_at <= ?
400 ORDER BY ip_address,submitted_at
400 ORDER BY ip_address,submitted_at
401 SQL
401 SQL
402 @subs = Submission.joins(:problem).find_by_sql([st,@since_time,@until_time,
402 @subs = Submission.joins(:problem).find_by_sql([st,@since_time,@until_time,
403 @since_time,@until_time,
403 @since_time,@until_time,
404 @since_time,@until_time,
404 @since_time,@until_time,
405 @since_time,@until_time])
405 @since_time,@until_time])
406
406
407 end
407 end
408
408
409 def cheat_scruntinize
409 def cheat_scruntinize
410 #convert date & time
410 #convert date & time
411 date_and_time = '%Y-%m-%d %H:%M'
411 date_and_time = '%Y-%m-%d %H:%M'
412 begin
412 begin
413 md = params[:since_datetime].match(/(\d+)-(\d+)-(\d+) (\d+):(\d+)/)
413 md = params[:since_datetime].match(/(\d+)-(\d+)-(\d+) (\d+):(\d+)/)
414 @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)
414 @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)
415 rescue
415 rescue
416 @since_time = Time.zone.now.ago( 90.minutes)
416 @since_time = Time.zone.now.ago( 90.minutes)
417 end
417 end
418 begin
418 begin
419 md = params[:until_datetime].match(/(\d+)-(\d+)-(\d+) (\d+):(\d+)/)
419 md = params[:until_datetime].match(/(\d+)-(\d+)-(\d+) (\d+):(\d+)/)
420 @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)
420 @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)
421 rescue
421 rescue
422 @until_time = Time.zone.now
422 @until_time = Time.zone.now
423 end
423 end
424
424
425 #convert sid
425 #convert sid
426 @sid = params[:SID].split(/[,\s]/) if params[:SID]
426 @sid = params[:SID].split(/[,\s]/) if params[:SID]
427 unless @sid and @sid.size > 0
427 unless @sid and @sid.size > 0
428 return
428 return
429 redirect_to actoin: :cheat_scruntinize
429 redirect_to actoin: :cheat_scruntinize
430 flash[:notice] = 'Please enter at least 1 student id'
430 flash[:notice] = 'Please enter at least 1 student id'
431 end
431 end
432 mark = Array.new(@sid.size,'?')
432 mark = Array.new(@sid.size,'?')
433 condition = "(u.login = " + mark.join(' OR u.login = ') + ')'
433 condition = "(u.login = " + mark.join(' OR u.login = ') + ')'
434
434
435 @st = <<-SQL
435 @st = <<-SQL
436 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
436 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
437 FROM logins l INNER JOIN users u on l.user_id = u.id
437 FROM logins l INNER JOIN users u on l.user_id = u.id
438 WHERE l.created_at >= ? AND l.created_at <= ? AND #{condition}
438 WHERE l.created_at >= ? AND l.created_at <= ? AND #{condition}
439 UNION
439 UNION
440 SELECT s.submitted_at,s.id,u.login,u.full_name,s.ip_address,s.problem_id,s.points,s.user_id
440 SELECT s.submitted_at,s.id,u.login,u.full_name,s.ip_address,s.problem_id,s.points,s.user_id
441 FROM submissions s INNER JOIN users u ON s.user_id = u.id
441 FROM submissions s INNER JOIN users u ON s.user_id = u.id
442 WHERE s.submitted_at >= ? AND s.submitted_at <= ? AND #{condition}
442 WHERE s.submitted_at >= ? AND s.submitted_at <= ? AND #{condition}
443 ORDER BY submitted_at
443 ORDER BY submitted_at
444 SQL
444 SQL
445
445
446 p = [@st,@since_time,@until_time] + @sid + [@since_time,@until_time] + @sid
446 p = [@st,@since_time,@until_time] + @sid + [@since_time,@until_time] + @sid
447 @logs = Submission.joins(:problem).find_by_sql(p)
447 @logs = Submission.joins(:problem).find_by_sql(p)
448
448
449
449
450
450
451
451
452
452
453 end
453 end
454
454
455 protected
455 protected
456
456
457 def calculate_max_score(problems, users,since_id,until_id, get_last_score = false)
457 def calculate_max_score(problems, users,since_id,until_id, get_last_score = false)
458 scorearray = Array.new
458 scorearray = Array.new
459 users.each do |u|
459 users.each do |u|
460 ustat = Array.new
460 ustat = Array.new
461 ustat[0] = u
461 ustat[0] = u
462 problems.each do |p|
462 problems.each do |p|
463 unless get_last_score
463 unless get_last_score
464 #get max score
464 #get max score
465 max_points = 0
465 max_points = 0
466 Submission.find_in_range_by_user_and_problem(u.id,p.id,since_id,until_id).each do |sub|
466 Submission.find_in_range_by_user_and_problem(u.id,p.id,since_id,until_id).each do |sub|
467 max_points = sub.points if sub and sub.points and (sub.points > max_points)
467 max_points = sub.points if sub and sub.points and (sub.points > max_points)
468 end
468 end
469 ustat << [(max_points.to_f*100/p.full_score).round, (max_points>=p.full_score)]
469 ustat << [(max_points.to_f*100/p.full_score).round, (max_points>=p.full_score)]
470 else
470 else
471 #get latest score
471 #get latest score
472 sub = Submission.find_last_by_user_and_problem(u.id,p.id)
472 sub = Submission.find_last_by_user_and_problem(u.id,p.id)
473 if (sub!=nil) and (sub.points!=nil) and p and p.full_score
473 if (sub!=nil) and (sub.points!=nil) and p and p.full_score
474 ustat << [(sub.points.to_f*100/p.full_score).round, (sub.points>=p.full_score)]
474 ustat << [(sub.points.to_f*100/p.full_score).round, (sub.points>=p.full_score)]
475 else
475 else
476 ustat << [0,false]
476 ustat << [0,false]
477 end
477 end
478 end
478 end
479 + end
479 scorearray << ustat
480 scorearray << ustat
480 end
481 end
481 return scorearray
482 return scorearray
482 end
483 end
483
484
484 end
485 end
You need to be logged in to leave comments. Login now