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

r722:83f5b778c08b - - 2 files changed: 30 inserted, 2 deleted

@@ -1,210 +1,213
1 1 require 'net/smtp'
2 2
3 3 class UsersController < ApplicationController
4 4
5 5 include MailHelperMethods
6 6
7 7 before_filter :authenticate, :except => [:new,
8 8 :register,
9 9 :confirm,
10 10 :forget,
11 11 :retrieve_password]
12 12
13 13 before_filter :verify_online_registration, :only => [:new,
14 14 :register,
15 15 :forget,
16 16 :retrieve_password]
17 17 before_filter :authenticate, :profile_authorization, only: [:profile]
18 18
19 + before_filter :admin_authorization, only: [:stat, :toggle_activate, :toggle_enable]
20 +
21 +
19 22 verify :method => :post, :only => [:chg_passwd],
20 23 :redirect_to => { :action => :index }
21 24
22 25 #in_place_edit_for :user, :alias_for_editing
23 26 #in_place_edit_for :user, :email_for_editing
24 27
25 28 def index
26 29 if !GraderConfiguration['system.user_setting_enabled']
27 30 redirect_to :controller => 'main', :action => 'list'
28 31 else
29 32 @user = User.find(session[:user_id])
30 33 end
31 34 end
32 35
33 36 def chg_passwd
34 37 user = User.find(session[:user_id])
35 38 user.password = params[:passwd]
36 39 user.password_confirmation = params[:passwd_verify]
37 40 if user.save
38 41 flash[:notice] = 'password changed'
39 42 else
40 43 flash[:notice] = 'Error: password changing failed'
41 44 end
42 45 redirect_to :action => 'index'
43 46 end
44 47
45 48 def new
46 49 @user = User.new
47 50 render :action => 'new', :layout => 'empty'
48 51 end
49 52
50 53 def register
51 54 if(params[:cancel])
52 55 redirect_to :controller => 'main', :action => 'login'
53 56 return
54 57 end
55 58 @user = User.new(user_params)
56 59 @user.password_confirmation = @user.password = User.random_password
57 60 @user.activated = false
58 61 if (@user.valid?) and (@user.save)
59 62 if send_confirmation_email(@user)
60 63 render :action => 'new_splash', :layout => 'empty'
61 64 else
62 65 @admin_email = GraderConfiguration['system.admin_email']
63 66 render :action => 'email_error', :layout => 'empty'
64 67 end
65 68 else
66 69 @user.errors.add(:base,"Email cannot be blank") if @user.email==''
67 70 render :action => 'new', :layout => 'empty'
68 71 end
69 72 end
70 73
71 74 def confirm
72 75 login = params[:login]
73 76 key = params[:activation]
74 77 @user = User.find_by_login(login)
75 78 if (@user) and (@user.verify_activation_key(key))
76 79 if @user.valid? # check uniquenss of email
77 80 @user.activated = true
78 81 @user.save
79 82 @result = :successful
80 83 else
81 84 @result = :email_used
82 85 end
83 86 else
84 87 @result = :failed
85 88 end
86 89 render :action => 'confirm', :layout => 'empty'
87 90 end
88 91
89 92 def forget
90 93 render :action => 'forget', :layout => 'empty'
91 94 end
92 95
93 96 def retrieve_password
94 97 email = params[:email]
95 98 user = User.find_by_email(email)
96 99 if user
97 100 last_updated_time = user.updated_at || user.created_at || (Time.now.gmtime - 1.hour)
98 101 if last_updated_time > Time.now.gmtime - 5.minutes
99 102 flash[:notice] = 'The account has recently created or new password has recently been requested. Please wait for 5 minutes'
100 103 else
101 104 user.password = user.password_confirmation = User.random_password
102 105 user.save
103 106 send_new_password_email(user)
104 107 flash[:notice] = 'New password has been mailed to you.'
105 108 end
106 109 else
107 110 flash[:notice] = I18n.t 'registration.password_retrieval.no_email'
108 111 end
109 112 redirect_to :action => 'forget'
110 113 end
111 114
112 115 def stat
113 116 @user = User.find(params[:id])
114 117 @submission = Submission.joins(:problem).where(user_id: params[:id])
115 118 @submission = @submission.where('problems.available = true') unless current_user.admin?
116 119
117 120 range = 120
118 121 @histogram = { data: Array.new(range,0), summary: {} }
119 122 @summary = {count: 0, solve: 0, attempt: 0}
120 123 problem = Hash.new(0)
121 124
122 125 @submission.find_each do |sub|
123 126 #histogram
124 127 d = (DateTime.now.in_time_zone - sub.submitted_at) / 24 / 60 / 60
125 128 @histogram[:data][d.to_i] += 1 if d < range
126 129
127 130 @summary[:count] += 1
128 131 next unless sub.problem
129 132 problem[sub.problem] = [problem[sub.problem], ( (sub.try(:points) || 0) >= sub.problem.full_score) ? 1 : 0].max
130 133 end
131 134
132 135 @histogram[:summary][:max] = [@histogram[:data].max,1].max
133 136 @summary[:attempt] = problem.count
134 137 problem.each_value { |v| @summary[:solve] += 1 if v == 1 }
135 138 end
136 139
137 140 def toggle_activate
138 141 @user = User.find(params[:id])
139 142 @user.update_attributes( activated: !@user.activated? )
140 143 respond_to do |format|
141 144 format.js { render partial: 'toggle_button',
142 145 locals: {button_id: "#toggle_activate_user_#{@user.id}",button_on: @user.activated? } }
143 146 end
144 147 end
145 148
146 149 def toggle_enable
147 150 @user = User.find(params[:id])
148 151 @user.update_attributes( enabled: !@user.enabled? )
149 152 respond_to do |format|
150 153 format.js { render partial: 'toggle_button',
151 154 locals: {button_id: "#toggle_enable_user_#{@user.id}",button_on: @user.enabled? } }
152 155 end
153 156 end
154 157
155 158 protected
156 159
157 160 def verify_online_registration
158 161 if !GraderConfiguration['system.online_registration']
159 162 redirect_to :controller => 'main', :action => 'login'
160 163 end
161 164 end
162 165
163 166 def send_confirmation_email(user)
164 167 contest_name = GraderConfiguration['contest.name']
165 168 activation_url = url_for(:action => 'confirm',
166 169 :login => user.login,
167 170 :activation => user.activation_key)
168 171 home_url = url_for(:controller => 'main', :action => 'index')
169 172 mail_subject = "[#{contest_name}] Confirmation"
170 173 mail_body = t('registration.email_body', {
171 174 :full_name => user.full_name,
172 175 :contest_name => contest_name,
173 176 :login => user.login,
174 177 :password => user.password,
175 178 :activation_url => activation_url,
176 179 :admin_email => GraderConfiguration['system.admin_email']
177 180 })
178 181
179 182 logger.info mail_body
180 183
181 184 send_mail(user.email, mail_subject, mail_body)
182 185 end
183 186
184 187 def send_new_password_email(user)
185 188 contest_name = GraderConfiguration['contest.name']
186 189 mail_subject = "[#{contest_name}] Password recovery"
187 190 mail_body = t('registration.password_retrieval.email_body', {
188 191 :full_name => user.full_name,
189 192 :contest_name => contest_name,
190 193 :login => user.login,
191 194 :password => user.password,
192 195 :admin_email => GraderConfiguration['system.admin_email']
193 196 })
194 197
195 198 logger.info mail_body
196 199
197 200 send_mail(user.email, mail_subject, mail_body)
198 201 end
199 202
200 203 # allow viewing of regular user profile only when options allow so
201 204 # only admins can view admins profile
202 205 def profile_authorization
203 206 #if view admins' profile, allow only admin
204 207 return false unless(params[:id])
205 208 user = User.find(params[:id])
206 209 return false unless user
207 210 return admin_authorization if user.admin?
208 211 return true if GraderConfiguration["right.user_view_submission"]
209 212
210 213 #finally, we allow only admin
@@ -1,245 +1,270
1 1 %h2 Live submit
2 2 %br
3 3
4 4 %textarea#text_sourcecode{style: "display:none"}~ @source
5 5 .container
6 6 .row
7 7 .col-md-12
8 8 .alert.alert-info
9 9 Write your code in the following box, choose language, and click submit button when finished
10 10 .row
11 11 .col-md-8
12 12 %div#editor{style: 'height: 500px; border-radius: 7px; font-size: 14px;'}
13 13 .col-md-4
14 14 - # submission form
15 15 = form_tag({controller: :main, :action => 'submit'}, :multipart => true, class: 'form') do
16 16
17 17 = hidden_field_tag 'editor_text', @source
18 18 = hidden_field_tag 'submission[problem_id]', @problem.id
19 19 .form-group
20 20 = label_tag "Task:"
21 21 = text_field_tag 'asdf', "#{@problem.long_name}", class: 'form-control', disabled: true
22 + .form-group
23 + = label_tag "Description:"
24 + = link_to_description_if_any "[download] <span class='glyphicon glyphicon-file'></span>".html_safe, @problem
22 25
23 26 .form-group
24 - = label_tag 'Language'
27 + = label_tag 'Language:'
25 28 = select_tag 'language_id', options_from_collection_for_select(Language.all, 'id', 'pretty_name', @lang_id || Language.find_by_pretty_name("Python").id || Language.first.id), class: 'form-control select', style: "width: 100px"
26 29 .form-group
30 + .input-group
31 + %span.input-group-btn
32 + %span.btn.btn-default.btn-file
33 + Browse
34 + = file_field_tag 'load_file'
35 + = text_field_tag '' , nil, {readonly: true, class: 'form-control'}
36 + .form-group
27 37 = submit_tag 'Submit', class: 'btn btn-success', id: 'live_submit',
28 38 data: {confirm: "Submitting this source code for task #{@problem.long_name}?"}
29 39 - # latest submission status
30 40 .panel{class: (@submission && @submission.graded_at) ? "panel-info" : "panel-warning"}
31 41 .panel-heading
32 42 Latest Submission Status
33 43 = link_to "Refresh",get_latest_submission_status_submissions_path(@submission.user,@problem), class: "btn btn-default btn-sm", remote: true if @submission
34 44 .panel-body
35 45 %div#latest_status
36 46 - if @submission
37 47 = render :partial => 'submission_short',
38 48 :locals => {submission: @submission, problem_name: @problem.name, problem_id: @problem.id }
39 49 .row
40 50 .col-md-12
41 51 %h2 Console
42 52 %textarea#console{style: 'height: 100%; width: 100%;background-color:#000;color:#fff;font-family: consolas, monaco, "Droid Sans Mono";',rows: 20}
43 53
44 54 :javascript
45 55 $(document).ready(function() {
46 56 e = ace.edit("editor")
47 57 e.setValue($("#text_sourcecode").val());
48 58 e.gotoLine(1);
49 59 $("#language_id").trigger('change');
50 - brython();
60 +
61 + $("#load_file").on('change',function(evt) {
62 + var file = evt.target.files[0];
63 + var reader = new FileReader();
64 + reader.onload = function(theFile) {
65 + var e = ace.edit("editor")
66 + e.setValue(theFile.target.result);
67 + e.gotoLine(1);
68 + };
69 + reader.readAsText(file)
70 + });
71 +
72 + //brython();
51 73 });
52 74
53 75
76 +
77 +
78 +
54 79 %script#__main__{type:'text/python3'}
55 80 :plain
56 81 import sys
57 82 import traceback
58 83
59 84 from browser import document as doc
60 85 from browser import window, alert, console
61 86
62 87 _credits = """ Thanks to CWI, CNRI, BeOpen.com, Zope Corporation and a cast of thousands
63 88 for supporting Python development. See www.python.org for more information."""
64 89
65 90 _copyright = """Copyright (c) 2012, Pierre Quentel pierre.quentel@gmail.com
66 91 All Rights Reserved.
67 92
68 93 Copyright (c) 2001-2013 Python Software Foundation.
69 94 All Rights Reserved.
70 95
71 96 Copyright (c) 2000 BeOpen.com.
72 97 All Rights Reserved.
73 98
74 99 Copyright (c) 1995-2001 Corporation for National Research Initiatives.
75 100 All Rights Reserved.
76 101
77 102 Copyright (c) 1991-1995 Stichting Mathematisch Centrum, Amsterdam.
78 103 All Rights Reserved."""
79 104
80 105 _license = """Copyright (c) 2012, Pierre Quentel pierre.quentel@gmail.com
81 106 All rights reserved.
82 107
83 108 Redistribution and use in source and binary forms, with or without
84 109 modification, are permitted provided that the following conditions are met:
85 110
86 111 Redistributions of source code must retain the above copyright notice, this
87 112 list of conditions and the following disclaimer. Redistributions in binary
88 113 form must reproduce the above copyright notice, this list of conditions and
89 114 the following disclaimer in the documentation and/or other materials provided
90 115 with the distribution.
91 116 Neither the name of the <ORGANIZATION> nor the names of its contributors may
92 117 be used to endorse or promote products derived from this software without
93 118 specific prior written permission.
94 119
95 120 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
96 121 AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
97 122 IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
98 123 ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
99 124 LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
100 125 CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
101 126 SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
102 127 INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
103 128 CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
104 129 ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
105 130 POSSIBILITY OF SUCH DAMAGE.
106 131 """
107 132
108 133 def credits():
109 134 print(_credits)
110 135 credits.__repr__ = lambda:_credits
111 136
112 137 def copyright():
113 138 print(_copyright)
114 139 copyright.__repr__ = lambda:_copyright
115 140
116 141 def license():
117 142 print(_license)
118 143 license.__repr__ = lambda:_license
119 144
120 145 def write(data):
121 146 doc['console'].value += str(data)
122 147
123 148
124 149 sys.stdout.write = sys.stderr.write = write
125 150 history = []
126 151 current = 0
127 152 _status = "main" # or "block" if typing inside a block
128 153
129 154 # execution namespace
130 155 editor_ns = {'credits':credits,
131 156 'copyright':copyright,
132 157 'license':license,
133 158 '__name__':'__main__'}
134 159
135 160 def cursorToEnd(*args):
136 161 pos = len(doc['console'].value)
137 162 doc['console'].setSelectionRange(pos, pos)
138 163 doc['console'].scrollTop = doc['console'].scrollHeight
139 164
140 165 def get_col(area):
141 166 # returns the column num of cursor
142 167 sel = doc['console'].selectionStart
143 168 lines = doc['console'].value.split('\n')
144 169 for line in lines[:-1]:
145 170 sel -= len(line) + 1
146 171 return sel
147 172
148 173
149 174 def myKeyPress(event):
150 175 global _status, current
151 176 if event.keyCode == 9: # tab key
152 177 event.preventDefault()
153 178 doc['console'].value += " "
154 179 elif event.keyCode == 13: # return
155 180 src = doc['console'].value
156 181 if _status == "main":
157 182 currentLine = src[src.rfind('>>>') + 4:]
158 183 elif _status == "3string":
159 184 currentLine = src[src.rfind('>>>') + 4:]
160 185 currentLine = currentLine.replace('\n... ', '\n')
161 186 else:
162 187 currentLine = src[src.rfind('...') + 4:]
163 188 if _status == 'main' and not currentLine.strip():
164 189 doc['console'].value += '\n>>> '
165 190 event.preventDefault()
166 191 return
167 192 doc['console'].value += '\n'
168 193 history.append(currentLine)
169 194 current = len(history)
170 195 if _status == "main" or _status == "3string":
171 196 try:
172 197 _ = editor_ns['_'] = eval(currentLine, editor_ns)
173 198 if _ is not None:
174 199 write(repr(_)+'\n')
175 200 doc['console'].value += '>>> '
176 201 _status = "main"
177 202 except IndentationError:
178 203 doc['console'].value += '... '
179 204 _status = "block"
180 205 except SyntaxError as msg:
181 206 if str(msg) == 'invalid syntax : triple string end not found' or \
182 207 str(msg).startswith('Unbalanced bracket'):
183 208 doc['console'].value += '... '
184 209 _status = "3string"
185 210 elif str(msg) == 'eval() argument must be an expression':
186 211 try:
187 212 exec(currentLine, editor_ns)
188 213 except:
189 214 traceback.print_exc()
190 215 doc['console'].value += '>>> '
191 216 _status = "main"
192 217 elif str(msg) == 'decorator expects function':
193 218 doc['console'].value += '... '
194 219 _status = "block"
195 220 else:
196 221 traceback.print_exc()
197 222 doc['console'].value += '>>> '
198 223 _status = "main"
199 224 except:
200 225 traceback.print_exc()
201 226 doc['console'].value += '>>> '
202 227 _status = "main"
203 228 elif currentLine == "": # end of block
204 229 block = src[src.rfind('>>>') + 4:].splitlines()
205 230 block = [block[0]] + [b[4:] for b in block[1:]]
206 231 block_src = '\n'.join(block)
207 232 # status must be set before executing code in globals()
208 233 _status = "main"
209 234 try:
210 235 _ = exec(block_src, editor_ns)
211 236 if _ is not None:
212 237 print(repr(_))
213 238 except:
214 239 traceback.print_exc()
215 240 doc['console'].value += '>>> '
216 241 else:
217 242 doc['console'].value += '... '
218 243
219 244 cursorToEnd()
220 245 event.preventDefault()
221 246
222 247 def myKeyDown(event):
223 248 global _status, current
224 249 if event.keyCode == 37: # left arrow
225 250 sel = get_col(doc['console'])
226 251 if sel < 5:
227 252 event.preventDefault()
228 253 event.stopPropagation()
229 254 elif event.keyCode == 36: # line start
230 255 pos = doc['console'].selectionStart
231 256 col = get_col(doc['console'])
232 257 doc['console'].setSelectionRange(pos - col + 4, pos - col + 4)
233 258 event.preventDefault()
234 259 elif event.keyCode == 38: # up
235 260 if current > 0:
236 261 pos = doc['console'].selectionStart
237 262 col = get_col(doc['console'])
238 263 # remove current line
239 264 doc['console'].value = doc['console'].value[:pos - col + 4]
240 265 current -= 1
241 266 doc['console'].value += history[current]
242 267 event.preventDefault()
243 268 elif event.keyCode == 40: # down
244 269 if current < len(history) - 1:
245 270 pos = doc['console'].selectionStart
You need to be logged in to leave comments. Login now