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

@@ -118,97 +118,97
118 render :action => 'edit'
118 render :action => 'edit'
119 end
119 end
120 end
120 end
121
121
122 def destroy
122 def destroy
123 Problem.find(params[:id]).destroy
123 Problem.find(params[:id]).destroy
124 redirect_to :action => 'list'
124 redirect_to :action => 'list'
125 end
125 end
126
126
127 def toggle
127 def toggle
128 @problem = Problem.find(params[:id])
128 @problem = Problem.find(params[:id])
129 @problem.available = !(@problem.available)
129 @problem.available = !(@problem.available)
130 @problem.save
130 @problem.save
131 end
131 end
132
132
133 def turn_all_off
133 def turn_all_off
134 Problem.find(:all,
134 Problem.find(:all,
135 :conditions => "available = 1").each do |problem|
135 :conditions => "available = 1").each do |problem|
136 problem.available = false
136 problem.available = false
137 problem.save
137 problem.save
138 end
138 end
139 redirect_to :action => 'list'
139 redirect_to :action => 'list'
140 end
140 end
141
141
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
191 def import
191 def import
192 @allow_test_pair_import = allow_test_pair_import?
192 @allow_test_pair_import = allow_test_pair_import?
193 end
193 end
194
194
195 def do_import
195 def do_import
196 old_problem = Problem.find_by_name(params[:name])
196 old_problem = Problem.find_by_name(params[:name])
197 if !allow_test_pair_import? and params.has_key? :import_to_db
197 if !allow_test_pair_import? and params.has_key? :import_to_db
198 params.delete :import_to_db
198 params.delete :import_to_db
199 end
199 end
200 @problem, import_log = Problem.create_from_import_form_params(params,
200 @problem, import_log = Problem.create_from_import_form_params(params,
201 old_problem)
201 old_problem)
202
202
203 if !@problem.errors.empty?
203 if !@problem.errors.empty?
204 render :action => 'import' and return
204 render :action => 'import' and return
205 end
205 end
206
206
207 if old_problem!=nil
207 if old_problem!=nil
208 flash[:notice] = "The test data has been replaced for problem #{@problem.name}"
208 flash[:notice] = "The test data has been replaced for problem #{@problem.name}"
209 end
209 end
210 @log = import_log
210 @log = import_log
211 end
211 end
212
212
213 def remove_contest
213 def remove_contest
214 problem = Problem.find(params[:id])
214 problem = Problem.find(params[:id])
@@ -171,61 +171,84
171 if @best[:memory][:value] >= prop[:memory][:value]
171 if @best[:memory][:value] >= prop[:memory][:value]
172 @best[:memory] = prop[:memory]
172 @best[:memory] = prop[:memory]
173 @best[:memory][:lang] = lang
173 @best[:memory][:lang] = lang
174 end
174 end
175 if @best[:length][:value] >= prop[:length][:value]
175 if @best[:length][:value] >= prop[:length][:value]
176 @best[:length] = prop[:length]
176 @best[:length] = prop[:length]
177 @best[:length][:lang] = lang
177 @best[:length][:lang] = lang
178 end
178 end
179 if @best[:first][:value] >= prop[:first][:value]
179 if @best[:first][:value] >= prop[:first][:value]
180 @best[:first] = prop[:first]
180 @best[:first] = prop[:first]
181 @best[:first][:lang] = lang
181 @best[:first][:lang] = lang
182 end
182 end
183 end
183 end
184 end
184 end
185
185
186 @histogram[:summary][:max] = [@histogram[:data].max,1].max
186 @histogram[:summary][:max] = [@histogram[:data].max,1].max
187 @summary[:attempt] = user.count
187 @summary[:attempt] = user.count
188 user.each_value { |v| @summary[:solve] += 1 if v == 1 }
188 user.each_value { |v| @summary[:solve] += 1 if v == 1 }
189 end
189 end
190
190
191 def stuck #report struggling user,problem
191 def stuck #report struggling user,problem
192 # init
192 # init
193 user,problem = nil
193 user,problem = nil
194 solve = true
194 solve = true
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
@@ -39,101 +39,106
39 @users = []
39 @users = []
40 sessions.each do |session|
40 sessions.each do |session|
41 if session.data[:user_id]
41 if session.data[:user_id]
42 @users << User.find(session.data[:user_id])
42 @users << User.find(session.data[:user_id])
43 end
43 end
44 end
44 end
45 end
45 end
46
46
47 def show
47 def show
48 @user = User.find(params[:id])
48 @user = User.find(params[:id])
49 end
49 end
50
50
51 def new
51 def new
52 @user = User.new
52 @user = User.new
53 end
53 end
54
54
55 def create
55 def create
56 @user = User.new(params[:user])
56 @user = User.new(params[:user])
57 @user.activated = true
57 @user.activated = true
58 if @user.save
58 if @user.save
59 flash[:notice] = 'User was successfully created.'
59 flash[:notice] = 'User was successfully created.'
60 redirect_to :action => 'list'
60 redirect_to :action => 'list'
61 else
61 else
62 render :action => 'new'
62 render :action => 'new'
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.'
116 redirect_to :action => 'show', :id => @user
121 redirect_to :action => 'show', :id => @user
117 else
122 else
118 render :action => 'edit'
123 render :action => 'edit'
119 end
124 end
120 end
125 end
121
126
122 def destroy
127 def destroy
123 User.find(params[:id]).destroy
128 User.find(params[:id]).destroy
124 redirect_to :action => 'list'
129 redirect_to :action => 'list'
125 end
130 end
126
131
127 def user_stat
132 def user_stat
128 if params[:commit] == 'download csv'
133 if params[:commit] == 'download csv'
129 @problems = Problem.all
134 @problems = Problem.all
130 else
135 else
131 @problems = Problem.find_available_problems
136 @problems = Problem.find_available_problems
132 end
137 end
133 @users = User.find(:all, :include => [:contests, :contest_stat])
138 @users = User.find(:all, :include => [:contests, :contest_stat])
134 @scorearray = Array.new
139 @scorearray = Array.new
135 @users.each do |u|
140 @users.each do |u|
136 ustat = Array.new
141 ustat = Array.new
137 ustat[0] = u
142 ustat[0] = u
138 @problems.each do |p|
143 @problems.each do |p|
139 sub = Submission.find_last_by_user_and_problem(u.id,p.id)
144 sub = Submission.find_last_by_user_and_problem(u.id,p.id)
@@ -1,64 +1,64
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'
41 end
41 end
42 append_to menu_items, "[#{I18n.t 'menu.log_out'}]", 'main', 'login'
42 append_to menu_items, "[#{I18n.t 'menu.log_out'}]", 'main', 'login'
43
43
44 menu_items.html_safe
44 menu_items.html_safe
45 end
45 end
46
46
47 def append_to(option,label, controller, action)
47 def append_to(option,label, controller, action)
48 option << ' ' if option!=''
48 option << ' ' if option!=''
49 option << link_to_unless_current(label,
49 option << link_to_unless_current(label,
50 :controller => controller,
50 :controller => controller,
51 :action => action)
51 :action => action)
52 end
52 end
53
53
54 def format_short_time(time)
54 def format_short_time(time)
55 now = Time.now.gmtime
55 now = Time.now.gmtime
56 st = ''
56 st = ''
57 if (time.yday != now.yday) or
57 if (time.yday != now.yday) or
58 (time.year != now.year)
58 (time.year != now.year)
59 st = time.strftime("%x ")
59 st = time.strftime("%x ")
60 end
60 end
61 st + time.strftime("%X")
61 st + time.strftime("%X")
62 end
62 end
63
63
64 def format_short_duration(duration)
64 def format_short_duration(duration)
@@ -22,101 +22,101
22
22
23 has_one :contest_stat, :class_name => "UserContestStat", :dependent => :destroy
23 has_one :contest_stat, :class_name => "UserContestStat", :dependent => :destroy
24
24
25 belongs_to :site
25 belongs_to :site
26 belongs_to :country
26 belongs_to :country
27
27
28 has_and_belongs_to_many :contests, :uniq => true, :order => 'name'
28 has_and_belongs_to_many :contests, :uniq => true, :order => 'name'
29
29
30 scope :activated_users, :conditions => {:activated => true}
30 scope :activated_users, :conditions => {:activated => true}
31
31
32 validates_presence_of :login
32 validates_presence_of :login
33 validates_uniqueness_of :login
33 validates_uniqueness_of :login
34 validates_format_of :login, :with => /^[\_A-Za-z0-9]+$/
34 validates_format_of :login, :with => /^[\_A-Za-z0-9]+$/
35 validates_length_of :login, :within => 3..30
35 validates_length_of :login, :within => 3..30
36
36
37 validates_presence_of :full_name
37 validates_presence_of :full_name
38 validates_length_of :full_name, :minimum => 1
38 validates_length_of :full_name, :minimum => 1
39
39
40 validates_presence_of :password, :if => :password_required?
40 validates_presence_of :password, :if => :password_required?
41 validates_length_of :password, :within => 4..20, :if => :password_required?
41 validates_length_of :password, :within => 4..20, :if => :password_required?
42 validates_confirmation_of :password, :if => :password_required?
42 validates_confirmation_of :password, :if => :password_required?
43
43
44 validates_format_of :email,
44 validates_format_of :email,
45 :with => /\A([^@\s]+)@((?:[-a-z0-9]+\.)+[a-z]{2,})\Z/i,
45 :with => /\A([^@\s]+)@((?:[-a-z0-9]+\.)+[a-z]{2,})\Z/i,
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
99 def authenticated_by_cucas?(password)
99 def authenticated_by_cucas?(password)
100 url = URI.parse('https://www.cas.chula.ac.th/cas/api/?q=studentAuthenticate')
100 url = URI.parse('https://www.cas.chula.ac.th/cas/api/?q=studentAuthenticate')
101 appid = '41508763e340d5858c00f8c1a0f5a2bb'
101 appid = '41508763e340d5858c00f8c1a0f5a2bb'
102 appsecret ='d9cbb5863091dbe186fded85722a1e31'
102 appsecret ='d9cbb5863091dbe186fded85722a1e31'
103 post_args = {
103 post_args = {
104 'appid' => appid,
104 'appid' => appid,
105 'appsecret' => appsecret,
105 'appsecret' => appsecret,
106 'username' => login,
106 'username' => login,
107 'password' => password
107 'password' => password
108 }
108 }
109
109
110 #simple call
110 #simple call
111 begin
111 begin
112 http = Net::HTTP.new('www.cas.chula.ac.th', 443)
112 http = Net::HTTP.new('www.cas.chula.ac.th', 443)
113 http.use_ssl = true
113 http.use_ssl = true
114 result = [ ]
114 result = [ ]
115 http.start do |http|
115 http.start do |http|
116 req = Net::HTTP::Post.new('/cas/api/?q=studentAuthenticate')
116 req = Net::HTTP::Post.new('/cas/api/?q=studentAuthenticate')
117 param = "appid=#{appid}&appsecret=#{appsecret}&username=#{login}&password=#{password}"
117 param = "appid=#{appid}&appsecret=#{appsecret}&username=#{login}&password=#{password}"
118 resp = http.request(req,param)
118 resp = http.request(req,param)
119 result = JSON.parse resp.body
119 result = JSON.parse resp.body
120 end
120 end
121 return true if result["type"] == "beanStudent"
121 return true if result["type"] == "beanStudent"
122 rescue
122 rescue
@@ -1,51 +1,53
1 :css
1 :css
2 .fix-width {
2 .fix-width {
3 font-family: "Consolas, Monaco, Droid Sans Mono,Mono, Monospace,Courier"
3 font-family: "Consolas, Monaco, Droid Sans Mono,Mono, Monospace,Courier"
4 }
4 }
5
5
6 %h1 Problem stat: #{@problem.name}
6 %h1 Problem stat: #{@problem.name}
7 %h2 Overview
7 %h2 Overview
8
8
9
9
10 %table.info
10 %table.info
11 %thead
11 %thead
12 %tr.info-head
12 %tr.info-head
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