Description:
finalize multiple_login, change default menu of report to multiple login
Commit status:
[Not Reviewed]
References:
Comments:
0 Commit comments 0 Inline Comments
Unresolved TODOs:
There are no unresolved TODOs
Add another comment

r521:5a22064770a9 - - 7 files changed: 64 inserted, 17 deleted

@@ -142,49 +142,49
142 def turn_all_on
142 def turn_all_on
143 Problem.find(:all,
143 Problem.find(:all,
144 :conditions => "available = 0").each do |problem|
144 :conditions => "available = 0").each do |problem|
145 problem.available = true
145 problem.available = true
146 problem.save
146 problem.save
147 end
147 end
148 redirect_to :action => 'list'
148 redirect_to :action => 'list'
149 end
149 end
150
150
151 def stat
151 def stat
152 @problem = Problem.find(params[:id])
152 @problem = Problem.find(params[:id])
153 unless @problem.available or session[:admin]
153 unless @problem.available or session[:admin]
154 redirect_to :controller => 'main', :action => 'list'
154 redirect_to :controller => 'main', :action => 'list'
155 return
155 return
156 end
156 end
157 @submissions = Submission.includes(:user).where(problem_id: params[:id]).order(:user_id,:id)
157 @submissions = Submission.includes(:user).where(problem_id: params[:id]).order(:user_id,:id)
158
158
159 #stat summary
159 #stat summary
160 range =65
160 range =65
161 @histogram = { data: Array.new(range,0), summary: {} }
161 @histogram = { data: Array.new(range,0), summary: {} }
162 user = Hash.new(0)
162 user = Hash.new(0)
163 @submissions.find_each do |sub|
163 @submissions.find_each do |sub|
164 d = (DateTime.now.in_time_zone - sub.submitted_at) / 24 / 60 / 60
164 d = (DateTime.now.in_time_zone - sub.submitted_at) / 24 / 60 / 60
165 @histogram[:data][d.to_i] += 1 if d < range
165 @histogram[:data][d.to_i] += 1 if d < range
166 - user[sub.user_id] = [user[sub.user_id], (sub.points >= @problem.full_score) ? 1 : 0].max
166 + user[sub.user_id] = [user[sub.user_id], (sub.try(:points) >= @problem.full_score) ? 1 : 0].max
167 end
167 end
168 @histogram[:summary][:max] = [@histogram[:data].max,1].max
168 @histogram[:summary][:max] = [@histogram[:data].max,1].max
169
169
170 @summary = { attempt: user.count, solve: 0 }
170 @summary = { attempt: user.count, solve: 0 }
171 user.each_value { |v| @summary[:solve] += 1 if v == 1 }
171 user.each_value { |v| @summary[:solve] += 1 if v == 1 }
172 end
172 end
173
173
174 def manage
174 def manage
175 @problems = Problem.find(:all, :order => 'date_added DESC')
175 @problems = Problem.find(:all, :order => 'date_added DESC')
176 end
176 end
177
177
178 def do_manage
178 def do_manage
179 if params.has_key? 'change_date_added'
179 if params.has_key? 'change_date_added'
180 change_date_added
180 change_date_added
181 elsif params.has_key? 'add_to_contest'
181 elsif params.has_key? 'add_to_contest'
182 add_to_contest
182 add_to_contest
183 elsif params.has_key? 'enable_problem'
183 elsif params.has_key? 'enable_problem'
184 set_available(true)
184 set_available(true)
185 elsif params.has_key? 'disable_problem'
185 elsif params.has_key? 'disable_problem'
186 set_available(false)
186 set_available(false)
187 end
187 end
188 redirect_to :action => 'manage'
188 redirect_to :action => 'manage'
189 end
189 end
190
190
@@ -195,37 +195,60
195 tries = 0
195 tries = 0
196 @struggle = Array.new
196 @struggle = Array.new
197 record = {}
197 record = {}
198 Submission.includes(:problem,:user).order(:problem_id,:user_id).find_each do |sub|
198 Submission.includes(:problem,:user).order(:problem_id,:user_id).find_each do |sub|
199 next unless sub.user and sub.problem
199 next unless sub.user and sub.problem
200 if user != sub.user_id or problem != sub.problem_id
200 if user != sub.user_id or problem != sub.problem_id
201 @struggle << { user: record[:user], problem: record[:problem], tries: tries } unless solve
201 @struggle << { user: record[:user], problem: record[:problem], tries: tries } unless solve
202 record = {user: sub.user, problem: sub.problem}
202 record = {user: sub.user, problem: sub.problem}
203 user,problem = sub.user_id, sub.problem_id
203 user,problem = sub.user_id, sub.problem_id
204 solve = false
204 solve = false
205 tries = 0
205 tries = 0
206 end
206 end
207 if sub.points >= sub.problem.full_score
207 if sub.points >= sub.problem.full_score
208 solve = true
208 solve = true
209 else
209 else
210 tries += 1
210 tries += 1
211 end
211 end
212 end
212 end
213 @struggle.sort!{|a,b| b[:tries] <=> a[:tries] }
213 @struggle.sort!{|a,b| b[:tries] <=> a[:tries] }
214 @struggle = @struggle[0..50]
214 @struggle = @struggle[0..50]
215 end
215 end
216
216
217
217
218 def multiple_login
218 def multiple_login
219 + #user with multiple IP
219 raw = Submission.joins(:user).joins(:problem).where("problems.available != 0").group("login,ip_address").order(:login)
220 raw = Submission.joins(:user).joins(:problem).where("problems.available != 0").group("login,ip_address").order(:login)
220 last,count = 0,0
221 last,count = 0,0
221 - @multiple = []
222 + first = 0
223 + @users = []
222 raw.each do |r|
224 raw.each do |r|
223 if last != r.user.login
225 if last != r.user.login
224 count = 1
226 count = 1
227 + last = r.user.login
228 + first = r
225 else
229 else
226 - @multiple << r
230 + @users << first if count == 1
231 + @users << r
232 + count += 1
233 + end
234 + end
235 +
236 + #IP with multiple user
237 + raw = Submission.joins(:user).joins(:problem).where("problems.available != 0").group("login,ip_address").order(:ip_address)
238 + last,count = 0,0
239 + first = 0
240 + @ip = []
241 + raw.each do |r|
242 + if last != r.ip_address
243 + count = 1
244 + last = r.ip_address
245 + first = r
246 + else
247 + @ip << first if count == 1
248 + @ip << r
249 + count += 1
227 end
250 end
228 end
251 end
229 end
252 end
230
253
231 end
254 end
@@ -63,53 +63,58
63 end
63 end
64 end
64 end
65
65
66 def create_from_list
66 def create_from_list
67 lines = params[:user_list]
67 lines = params[:user_list]
68
68
69 note = []
69 note = []
70
70
71 lines.split("\n").each do |line|
71 lines.split("\n").each do |line|
72 items = line.chomp.split(',')
72 items = line.chomp.split(',')
73 if items.length>=2
73 if items.length>=2
74 login = items[0]
74 login = items[0]
75 full_name = items[1]
75 full_name = items[1]
76
76
77 added_random_password = false
77 added_random_password = false
78 if items.length>=3
78 if items.length>=3
79 password = items[2].chomp(" ")
79 password = items[2].chomp(" ")
80 user_alias = (items.length>=4) ? items[3] : login
80 user_alias = (items.length>=4) ? items[3] : login
81 else
81 else
82 password = random_password
82 password = random_password
83 user_alias = (items.length>=4) ? items[3] : login
83 user_alias = (items.length>=4) ? items[3] : login
84 added_random_password = true
84 added_random_password = true
85 end
85 end
86
86
87 - user = User.new({:login => login,
87 + user = User.find_by_login(login)
88 - :full_name => full_name,
88 + if user
89 - :password => password,
89 + user.password = password
90 - :password_confirmation => password,
90 + else
91 - :alias => user_alias})
91 + user = User.new({:login => login,
92 + :full_name => full_name,
93 + :password => password,
94 + :password_confirmation => password,
95 + :alias => user_alias})
96 + end
92 user.activated = true
97 user.activated = true
93 user.save
98 user.save
94
99
95 if added_random_password
100 if added_random_password
96 note << "'#{login}' (+)"
101 note << "'#{login}' (+)"
97 else
102 else
98 note << login
103 note << login
99 end
104 end
100 end
105 end
101 end
106 end
102 flash[:notice] = 'User(s) ' + note.join(', ') +
107 flash[:notice] = 'User(s) ' + note.join(', ') +
103 ' were successfully created. ' +
108 ' were successfully created. ' +
104 '( (+) - created with random passwords.)'
109 '( (+) - created with random passwords.)'
105 redirect_to :action => 'list'
110 redirect_to :action => 'list'
106 end
111 end
107
112
108 def edit
113 def edit
109 @user = User.find(params[:id])
114 @user = User.find(params[:id])
110 end
115 end
111
116
112 def update
117 def update
113 @user = User.find(params[:id])
118 @user = User.find(params[:id])
114 if @user.update_attributes(params[:user])
119 if @user.update_attributes(params[:user])
115 flash[:notice] = 'User was successfully updated.'
120 flash[:notice] = 'User was successfully updated.'
@@ -1,40 +1,40
1 # Methods added to this helper will be available to all templates in the application.
1 # Methods added to this helper will be available to all templates in the application.
2 module ApplicationHelper
2 module ApplicationHelper
3
3
4 def user_header
4 def user_header
5 menu_items = ''
5 menu_items = ''
6 user = User.find(session[:user_id])
6 user = User.find(session[:user_id])
7
7
8 if (user!=nil) and (session[:admin])
8 if (user!=nil) and (session[:admin])
9 # admin menu
9 # admin menu
10 menu_items << "<b>Administrative task:</b> "
10 menu_items << "<b>Administrative task:</b> "
11 append_to menu_items, '[Announcements]', 'announcements', 'index'
11 append_to menu_items, '[Announcements]', 'announcements', 'index'
12 append_to menu_items, '[Msg console]', 'messages', 'console'
12 append_to menu_items, '[Msg console]', 'messages', 'console'
13 append_to menu_items, '[Problems]', 'problems', 'index'
13 append_to menu_items, '[Problems]', 'problems', 'index'
14 append_to menu_items, '[Users]', 'user_admin', 'index'
14 append_to menu_items, '[Users]', 'user_admin', 'index'
15 append_to menu_items, '[Results]', 'user_admin', 'user_stat'
15 append_to menu_items, '[Results]', 'user_admin', 'user_stat'
16 - append_to menu_items, '[Report]', 'report', 'login_stat'
16 + append_to menu_items, '[Report]', 'report', 'multiple_login'
17 append_to menu_items, '[Graders]', 'graders', 'list'
17 append_to menu_items, '[Graders]', 'graders', 'list'
18 append_to menu_items, '[Contests]', 'contest_management', 'index'
18 append_to menu_items, '[Contests]', 'contest_management', 'index'
19 append_to menu_items, '[Sites]', 'sites', 'index'
19 append_to menu_items, '[Sites]', 'sites', 'index'
20 append_to menu_items, '[System config]', 'configurations', 'index'
20 append_to menu_items, '[System config]', 'configurations', 'index'
21 menu_items << "<br/>"
21 menu_items << "<br/>"
22 end
22 end
23
23
24 # main page
24 # main page
25 append_to menu_items, "[#{I18n.t 'menu.main'}]", 'main', 'list'
25 append_to menu_items, "[#{I18n.t 'menu.main'}]", 'main', 'list'
26 append_to menu_items, "[#{I18n.t 'menu.messages'}]", 'messages', 'list'
26 append_to menu_items, "[#{I18n.t 'menu.messages'}]", 'messages', 'list'
27
27
28 if (user!=nil) and (GraderConfiguration.show_tasks_to?(user))
28 if (user!=nil) and (GraderConfiguration.show_tasks_to?(user))
29 append_to menu_items, "[#{I18n.t 'menu.tasks'}]", 'tasks', 'list'
29 append_to menu_items, "[#{I18n.t 'menu.tasks'}]", 'tasks', 'list'
30 append_to menu_items, "[#{I18n.t 'menu.submissions'}]", 'main', 'submission'
30 append_to menu_items, "[#{I18n.t 'menu.submissions'}]", 'main', 'submission'
31 append_to menu_items, "[#{I18n.t 'menu.test'}]", 'test', 'index'
31 append_to menu_items, "[#{I18n.t 'menu.test'}]", 'test', 'index'
32 end
32 end
33
33
34 if GraderConfiguration['right.user_hall_of_fame']
34 if GraderConfiguration['right.user_hall_of_fame']
35 append_to menu_items, "[#{I18n.t 'menu.hall_of_fame'}]", 'report', 'problem_hof'
35 append_to menu_items, "[#{I18n.t 'menu.hall_of_fame'}]", 'report', 'problem_hof'
36 end
36 end
37 append_to menu_items, "[#{I18n.t 'menu.help'}]", 'main', 'help'
37 append_to menu_items, "[#{I18n.t 'menu.help'}]", 'main', 'help'
38
38
39 if GraderConfiguration['system.user_setting_enabled']
39 if GraderConfiguration['system.user_setting_enabled']
40 append_to menu_items, "[#{I18n.t 'menu.settings'}]", 'users', 'index'
40 append_to menu_items, "[#{I18n.t 'menu.settings'}]", 'users', 'index'
@@ -46,53 +46,53
46 :if => :email_validation?
46 :if => :email_validation?
47 validate :uniqueness_of_email_from_activated_users,
47 validate :uniqueness_of_email_from_activated_users,
48 :if => :email_validation?
48 :if => :email_validation?
49 validate :enough_time_interval_between_same_email_registrations,
49 validate :enough_time_interval_between_same_email_registrations,
50 :if => :email_validation?
50 :if => :email_validation?
51
51
52 # these are for ytopc
52 # these are for ytopc
53 # disable for now
53 # disable for now
54 #validates_presence_of :province
54 #validates_presence_of :province
55
55
56 attr_accessor :password
56 attr_accessor :password
57
57
58 before_save :encrypt_new_password
58 before_save :encrypt_new_password
59 before_save :assign_default_site
59 before_save :assign_default_site
60 before_save :assign_default_contest
60 before_save :assign_default_contest
61
61
62 # this is for will_paginate
62 # this is for will_paginate
63 cattr_reader :per_page
63 cattr_reader :per_page
64 @@per_page = 50
64 @@per_page = 50
65
65
66 def self.authenticate(login, password)
66 def self.authenticate(login, password)
67 user = find_by_login(login)
67 user = find_by_login(login)
68 if user
68 if user
69 return user if user.authenticated?(password)
69 return user if user.authenticated?(password)
70 - if user.authenticated_by_cucas?(password) or user.authenticated_by_pop3?(password)
70 + # if user.authenticated_by_cucas?(password) or user.authenticated_by_pop3?(password)
71 - user.password = password
71 + # user.password = password
72 - user.save
72 + # user.save
73 - return user
73 + # return user
74 - end
74 + # end
75 end
75 end
76 end
76 end
77
77
78 def authenticated?(password)
78 def authenticated?(password)
79 if self.activated
79 if self.activated
80 hashed_password == User.encrypt(password,self.salt)
80 hashed_password == User.encrypt(password,self.salt)
81 else
81 else
82 false
82 false
83 end
83 end
84 end
84 end
85
85
86 def authenticated_by_pop3?(password)
86 def authenticated_by_pop3?(password)
87 Net::POP3.enable_ssl
87 Net::POP3.enable_ssl
88 pop = Net::POP3.new('pops.it.chula.ac.th')
88 pop = Net::POP3.new('pops.it.chula.ac.th')
89 authen = true
89 authen = true
90 begin
90 begin
91 pop.start(login, password)
91 pop.start(login, password)
92 pop.finish
92 pop.finish
93 return true
93 return true
94 rescue
94 rescue
95 return false
95 return false
96 end
96 end
97 end
97 end
98
98
@@ -13,39 +13,41
13 %th Stat
13 %th Stat
14 %th Value
14 %th Value
15 %tbody
15 %tbody
16 %tr{class: cycle('info-even','info-odd')}
16 %tr{class: cycle('info-even','info-odd')}
17 %td Submissions
17 %td Submissions
18 %td= @submissions.count
18 %td= @submissions.count
19 %tr{class: cycle('info-even','info-odd')}
19 %tr{class: cycle('info-even','info-odd')}
20 %td Solved/Attempted User
20 %td Solved/Attempted User
21 %td #{@summary[:solve]}/#{@summary[:attempt]} (#{(@summary[:solve]*100.0/@summary[:attempt]).round(1)}%)
21 %td #{@summary[:solve]}/#{@summary[:attempt]} (#{(@summary[:solve]*100.0/@summary[:attempt]).round(1)}%)
22
22
23 %h2 Submissions Count
23 %h2 Submissions Count
24 = render partial: 'application/bar_graph', locals: { histogram: @histogram }
24 = render partial: 'application/bar_graph', locals: { histogram: @histogram }
25
25
26 %h2 Submissions
26 %h2 Submissions
27 - if @submissions and @submissions.count > 0
27 - if @submissions and @submissions.count > 0
28 %table.info#main_table
28 %table.info#main_table
29 %thead
29 %thead
30 %tr.info-head
30 %tr.info-head
31 %th ID
31 %th ID
32 %th Login
32 %th Login
33 %th Name
33 %th Name
34 %th Submitted_at
34 %th Submitted_at
35 %th Points
35 %th Points
36 %th comment
36 %th comment
37 + %th IP
37 %tbody
38 %tbody
38 - row_odd,curr = true,''
39 - row_odd,curr = true,''
39 - @submissions.each do |sub|
40 - @submissions.each do |sub|
40 - next unless sub.user
41 - next unless sub.user
41 - row_odd,curr = !row_odd, sub.user if curr != sub.user
42 - row_odd,curr = !row_odd, sub.user if curr != sub.user
42 %tr{class: row_odd ? "info-odd" : "info-even"}
43 %tr{class: row_odd ? "info-odd" : "info-even"}
43 %td= link_to sub.id, controller: 'graders', action: 'submission', id: sub.id
44 %td= link_to sub.id, controller: 'graders', action: 'submission', id: sub.id
44 %td= link_to sub.user.login, controller: :users, action: :profile, id: sub.user.id
45 %td= link_to sub.user.login, controller: :users, action: :profile, id: sub.user.id
45 %td= sub.user.full_name
46 %td= sub.user.full_name
46 %td= time_ago_in_words(sub.submitted_at) + " ago"
47 %td= time_ago_in_words(sub.submitted_at) + " ago"
47 %td= sub.points
48 %td= sub.points
48 %td.fix-width= sub.grader_comment
49 %td.fix-width= sub.grader_comment
50 + %td= sub.ip_address
49 - else
51 - else
50 No submission
52 No submission
51
53
@@ -1,20 +1,37
1 - content_for :header do
1 - content_for :header do
2 = stylesheet_link_tag 'tablesorter-theme.cafe'
2 = stylesheet_link_tag 'tablesorter-theme.cafe'
3 = javascript_include_tag 'local_jquery'
3 = javascript_include_tag 'local_jquery'
4
4
5 %h1 Login status
5 %h1 Login status
6
6
7 =render partial: 'report_menu'
7 =render partial: 'report_menu'
8
8
9 + Checking for all submissions with the currently available problem
10 +
11 + %h2 Users with Multiple IP
9 %table.tablesorter-cafe#my_table
12 %table.tablesorter-cafe#my_table
10 %thead
13 %thead
11 %tr
14 %tr
12 %th login
15 %th login
13 %th full name
16 %th full name
14 %th IP
17 %th IP
15 %tbody
18 %tbody
16 - - @multiple.each do |l|
19 + - @users.each do |l|
17 %tr{class: cycle('info-even','info-odd')}
20 %tr{class: cycle('info-even','info-odd')}
18 - %td= link_to l[:login], controller: 'users', action: 'profile', id: l[:id]
21 + %td= link_to l.user.login, controller: 'users', action: 'profile', id: l[:id]
19 - %td= l[:full_name]
22 + %td= l.user.full_name
20 %td= l[:ip_address]
23 %td= l[:ip_address]
24 +
25 + %h2 IP with multiple users
26 + %table.tablesorter-cafe#my_table
27 + %thead
28 + %tr
29 + %th IP
30 + %th login
31 + %th full name
32 + %tbody
33 + - @ip.each do |l|
34 + %tr{class: cycle('info-even','info-odd')}
35 + %td= l[:ip_address]
36 + %td= link_to l.user.login, controller: 'users', action: 'profile', id: l[:id]
37 + %td= l.user.full_name
You need to be logged in to leave comments. Login now