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

r665:ecbd1a5dbc27 - - 7 files changed: 108 inserted, 8 deleted

@@ -0,0 +1,34
1 + .container-fluid
2 + %h1 Editing announcement
3 + = error_messages_for :announcement
4 + .row
5 + .col-md-6
6 + = form_for(@announcement) do |f|
7 + .form-group
8 + %label Title
9 + = f.text_field :title, class: 'form-control'
10 + .form-group
11 + %label Notes
12 + (shown internally, used to organize announcements)
13 + = f.text_field :notes, class: 'form-control'
14 + .form-group
15 + %label Body
16 + = f.text_area :body, class: 'form-control', style: 'height: 200px;'
17 + .form-group
18 + %label Author
19 + = f.text_field :author, class: 'form-control'
20 + .checkbox
21 + %label
22 + = f.check_box :published
23 + Published
24 + .checkbox
25 + %label
26 + = f.check_box :frontpage
27 + Show on front page?
28 + .checkbox
29 + %label
30 + = f.check_box :contest_only
31 + Show only in contest?
32 + = f.submit "Update", class: 'btn btn-primary'
33 + = link_to 'Show', @announcement, class: 'btn btn-default'
34 + = link_to 'Back', announcements_path, class: 'btn btn-default'
@@ -0,0 +1,52
1 + = error_messages_for 'problem'
2 + / [form:problem]
3 + .form-group
4 + %label{:for => "problem_name"} Name
5 + = text_field 'problem', 'name', class: 'form-control'
6 + %small
7 + Do not directly edit the problem name, unless you know what you are doing. If you want to change the name, use the name change button in the problem management menu instead.
8 + .form-group
9 + %label{:for => "problem_full_name"} Full name
10 + = text_field 'problem', 'full_name', class: 'form-control'
11 + .form-group
12 + %label{:for => "problem_full_score"} Full score
13 + = text_field 'problem', 'full_score', class: 'form-control'
14 + .form-group
15 + %label{:for => "problem_date_added"} Date added
16 + = date_select 'problem', 'date_added', class: 'form-control'
17 + - # TODO: these should be put in model Problem, but I can't think of
18 + - # nice default values for them. These values look fine only
19 + - # in this case (of lazily adding new problems).
20 + - @problem.available = true if @problem!=nil and @problem.available==nil
21 + - @problem.test_allowed = true if @problem!=nil and @problem.test_allowed==nil
22 + - @problem.output_only = false if @problem!=nil and @problem.output_only==nil
23 + .checkbox
24 + %label{:for => "problem_available"}
25 + = check_box :problem, :available
26 + Available?
27 + .checkbox
28 + %label{:for => "problem_test_allowed"}
29 + = check_box :problem, :test_allowed
30 + Test allowed?
31 + .checkbox
32 + %label{:for => "problem_output_only"}
33 + = check_box :problem, :output_only
34 + Output only?
35 + = error_messages_for 'description'
36 + .form-group
37 + %label{:for => "description_body"} Description
38 + %br/
39 + = text_area :description, :body, :rows => 10, :cols => 80,class: 'form-control'
40 + .form-group
41 + %label{:for => "description_markdowned"} Markdowned?
42 + = select "description", |
43 + "markdowned", |
44 + [['True',true],['False',false]], |
45 + {:selected => (@description) ? @description.markdowned : false } |
46 + .form-group
47 + %label{:for => "problem_url"} URL
48 + %br/
49 + = text_field 'problem', 'url',class: 'form-control'
50 + %p
51 + Task PDF #{file_field_tag 'file'}
52 + / [eoform:problem]
@@ -0,0 +1,14
1 + .container-fluid
2 + = form_for @problem,url:{action: 'update'},html: {multipart: true} do
3 + .row
4 + .col-md-6
5 + %h1 Editing problem
6 + = render :partial => 'form'
7 + .row
8 + .col-md-4
9 + = submit_tag 'Edit', class: 'btn btn-primary btn-block'
10 + .col-md-4
11 + = link_to 'Show', {:action => 'show', :id => @problem}, class: 'btn btn-default btn-block'
12 + .col-md-4
13 + = link_to 'Back', problems_path, class: 'btn btn-default btn-block'
14 + .div{style: 'height: 5em'}
@@ -0,0 +1,5
1 + require 'spec_helper'
2 +
3 + describe Testcases do
4 + pending "add some examples to (or delete) #{__FILE__}"
5 + end
@@ -180,97 +180,97
180 180 begin
181 181 @problem = Problem.available.find(params[:id])
182 182 rescue
183 183 redirect_to action: :problem_hof
184 184 flash[:notice] = 'Error: submissions for that problem are not viewable.'
185 185 return
186 186 end
187 187 end
188 188
189 189 return unless @problem
190 190
191 191 @by_lang = {} #aggregrate by language
192 192
193 193 range =65
194 194 @histogram = { data: Array.new(range,0), summary: {} }
195 195 @summary = {count: 0, solve: 0, attempt: 0}
196 196 user = Hash.new(0)
197 197 Submission.where(problem_id: @problem.id).find_each do |sub|
198 198 #histogram
199 199 d = (DateTime.now.in_time_zone - sub.submitted_at) / 24 / 60 / 60
200 200 @histogram[:data][d.to_i] += 1 if d < range
201 201
202 202 next unless sub.points
203 203 @summary[:count] += 1
204 204 user[sub.user_id] = [user[sub.user_id], (sub.points >= @problem.full_score) ? 1 : 0].max
205 205
206 206 lang = Language.find_by_id(sub.language_id)
207 207 next unless lang
208 208 next unless sub.points >= @problem.full_score
209 209
210 210 #initialize
211 211 unless @by_lang.has_key?(lang.pretty_name)
212 212 @by_lang[lang.pretty_name] = {
213 213 runtime: { avail: false, value: 2**30-1 },
214 214 memory: { avail: false, value: 2**30-1 },
215 215 length: { avail: false, value: 2**30-1 },
216 216 first: { avail: false, value: DateTime.new(3000,1,1) }
217 217 }
218 218 end
219 219
220 220 if sub.max_runtime and sub.max_runtime < @by_lang[lang.pretty_name][:runtime][:value]
221 221 @by_lang[lang.pretty_name][:runtime] = { avail: true, user_id: sub.user_id, value: sub.max_runtime, sub_id: sub.id }
222 222 end
223 223
224 224 if sub.peak_memory and sub.peak_memory < @by_lang[lang.pretty_name][:memory][:value]
225 225 @by_lang[lang.pretty_name][:memory] = { avail: true, user_id: sub.user_id, value: sub.peak_memory, sub_id: sub.id }
226 226 end
227 227
228 - if sub.submitted_at and sub.submitted_at < @by_lang[lang.pretty_name][:first][:value] and
228 + if sub.submitted_at and sub.submitted_at < @by_lang[lang.pretty_name][:first][:value] and sub.user and
229 229 !sub.user.admin?
230 230 @by_lang[lang.pretty_name][:first] = { avail: true, user_id: sub.user_id, value: sub.submitted_at, sub_id: sub.id }
231 231 end
232 232
233 233 if @by_lang[lang.pretty_name][:length][:value] > sub.effective_code_length
234 234 @by_lang[lang.pretty_name][:length] = { avail: true, user_id: sub.user_id, value: sub.effective_code_length, sub_id: sub.id }
235 235 end
236 236 end
237 237
238 238 #process user_id
239 239 @by_lang.each do |lang,prop|
240 240 prop.each do |k,v|
241 241 v[:user] = User.exists?(v[:user_id]) ? User.find(v[:user_id]).full_name : "(NULL)"
242 242 end
243 243 end
244 244
245 245 #sum into best
246 246 if @by_lang and @by_lang.first
247 247 @best = @by_lang.first[1].clone
248 248 @by_lang.each do |lang,prop|
249 249 if @best[:runtime][:value] >= prop[:runtime][:value]
250 250 @best[:runtime] = prop[:runtime]
251 251 @best[:runtime][:lang] = lang
252 252 end
253 253 if @best[:memory][:value] >= prop[:memory][:value]
254 254 @best[:memory] = prop[:memory]
255 255 @best[:memory][:lang] = lang
256 256 end
257 257 if @best[:length][:value] >= prop[:length][:value]
258 258 @best[:length] = prop[:length]
259 259 @best[:length][:lang] = lang
260 260 end
261 261 if @best[:first][:value] >= prop[:first][:value]
262 262 @best[:first] = prop[:first]
263 263 @best[:first][:lang] = lang
264 264 end
265 265 end
266 266 end
267 267
268 268 @histogram[:summary][:max] = [@histogram[:data].max,1].max
269 269 @summary[:attempt] = user.count
270 270 user.each_value { |v| @summary[:solve] += 1 if v == 1 }
271 271 end
272 272
273 273 def stuck #report struggling user,problem
274 274 # init
275 275 user,problem = nil
276 276 solve = true
@@ -66,97 +66,98
66 66 @user.errors.add(:base,"Email cannot be blank") if @user.email==''
67 67 render :action => 'new', :layout => 'empty'
68 68 end
69 69 end
70 70
71 71 def confirm
72 72 login = params[:login]
73 73 key = params[:activation]
74 74 @user = User.find_by_login(login)
75 75 if (@user) and (@user.verify_activation_key(key))
76 76 if @user.valid? # check uniquenss of email
77 77 @user.activated = true
78 78 @user.save
79 79 @result = :successful
80 80 else
81 81 @result = :email_used
82 82 end
83 83 else
84 84 @result = :failed
85 85 end
86 86 render :action => 'confirm', :layout => 'empty'
87 87 end
88 88
89 89 def forget
90 90 render :action => 'forget', :layout => 'empty'
91 91 end
92 92
93 93 def retrieve_password
94 94 email = params[:email]
95 95 user = User.find_by_email(email)
96 96 if user
97 97 last_updated_time = user.updated_at || user.created_at || (Time.now.gmtime - 1.hour)
98 98 if last_updated_time > Time.now.gmtime - 5.minutes
99 99 flash[:notice] = 'The account has recently created or new password has recently been requested. Please wait for 5 minutes'
100 100 else
101 101 user.password = user.password_confirmation = User.random_password
102 102 user.save
103 103 send_new_password_email(user)
104 104 flash[:notice] = 'New password has been mailed to you.'
105 105 end
106 106 else
107 107 flash[:notice] = I18n.t 'registration.password_retrieval.no_email'
108 108 end
109 109 redirect_to :action => 'forget'
110 110 end
111 111
112 112 def stat
113 113 @user = User.find(params[:id])
114 - @submission = Submission.includes(:problem).where(user_id: params[:id])
114 + @submission = Submission.joins(:problem).where(user_id: params[:id])
115 + @submission = @submission.where('problems.available = true') unless current_user.admin?
115 116
116 117 range = 120
117 118 @histogram = { data: Array.new(range,0), summary: {} }
118 119 @summary = {count: 0, solve: 0, attempt: 0}
119 120 problem = Hash.new(0)
120 121
121 122 @submission.find_each do |sub|
122 123 #histogram
123 124 d = (DateTime.now.in_time_zone - sub.submitted_at) / 24 / 60 / 60
124 125 @histogram[:data][d.to_i] += 1 if d < range
125 126
126 127 @summary[:count] += 1
127 128 next unless sub.problem
128 129 problem[sub.problem] = [problem[sub.problem], ( (sub.try(:points) || 0) >= sub.problem.full_score) ? 1 : 0].max
129 130 end
130 131
131 132 @histogram[:summary][:max] = [@histogram[:data].max,1].max
132 133 @summary[:attempt] = problem.count
133 134 problem.each_value { |v| @summary[:solve] += 1 if v == 1 }
134 135 end
135 136
136 137 def toggle_activate
137 138 @user = User.find(params[:id])
138 139 @user.update_attributes( activated: !@user.activated? )
139 140 respond_to do |format|
140 141 format.js { render partial: 'toggle_button',
141 142 locals: {button_id: "#toggle_activate_user_#{@user.id}",button_on: @user.activated? } }
142 143 end
143 144 end
144 145
145 146 def toggle_enable
146 147 @user = User.find(params[:id])
147 148 @user.update_attributes( enabled: !@user.enabled? )
148 149 respond_to do |format|
149 150 format.js { render partial: 'toggle_button',
150 151 locals: {button_id: "#toggle_enable_user_#{@user.id}",button_on: @user.enabled? } }
151 152 end
152 153 end
153 154
154 155 protected
155 156
156 157 def verify_online_registration
157 158 if !GraderConfiguration['system.online_registration']
158 159 redirect_to :controller => 'main', :action => 'login'
159 160 end
160 161 end
161 162
162 163 def send_confirmation_email(user)
@@ -2,77 +2,71
2 2
3 3 require 'rails/all'
4 4
5 5 if defined?(Bundler)
6 6 # If you precompile assets before deploying to production, use this line
7 7 Bundler.require(*Rails.groups(:assets => %w(development test)))
8 8 # If you want your assets lazily compiled in production, use this line
9 9 # Bundler.require(:default, :assets, Rails.env)
10 10 end
11 11
12 12 module CafeGrader
13 13 class Application < Rails::Application
14 14 # Settings in config/environments/* take precedence over those specified here.
15 15 # Application configuration should go into files in config/initializers
16 16 # -- all .rb files in that directory are automatically loaded.
17 17
18 18 # Custom directories with classes and modules you want to be autoloadable.
19 19 config.autoload_paths += %W(#{config.root}/lib)
20 20
21 21 # Only load the plugins named here, in the order given (default is alphabetical).
22 22 # :all can be used as a placeholder for all plugins not explicitly named.
23 23 # config.plugins = [ :exception_notification, :ssl_requirement, :all ]
24 24
25 25 # Activate observers that should always be running.
26 26 # config.active_record.observers = :cacher, :garbage_collector, :forum_observer
27 27
28 28 # Set Time.zone default to the specified zone and make Active Record auto-convert to this zone.
29 29 # Run "rake -D time" for a list of tasks for finding time zone names. Default is UTC.
30 30 config.time_zone = 'UTC'
31 31
32 32 # The default locale is :en and all translations from config/locales/*.rb,yml are auto loaded.
33 33 # config.i18n.load_path += Dir[Rails.root.join('my', 'locales', '*.{rb,yml}').to_s]
34 34 config.i18n.default_locale = :en
35 35
36 36 # Configure the default encoding used in templates for Ruby 1.9.
37 37 config.encoding = "utf-8"
38 38
39 39 # Configure sensitive parameters which will be filtered from the log file.
40 40 config.filter_parameters += [:password]
41 41
42 42 # Enable escaping HTML in JSON.
43 43 config.active_support.escape_html_entities_in_json = true
44 44
45 45 # Use SQL instead of Active Record's schema dumper when creating the database.
46 46 # This is necessary if your schema can't be completely dumped by the schema dumper,
47 47 # like if you have constraints or database-specific column types
48 48 # config.active_record.schema_format = :sql
49 49
50 - # Enforce whitelist mode for mass assignment.
51 - # This will create an empty whitelist of attributes available for mass-assignment for all models
52 - # in your app. As such, your models will need to explicitly whitelist or blacklist accessible
53 - # parameters by using an attr_accessible or attr_protected declaration.
54 - config.active_record.whitelist_attributes = false
55 -
56 50 # Enable the asset pipeline
57 51 config.assets.enabled = true
58 52
59 53 # Version of your assets, change this if you want to expire all your assets
60 54 config.assets.version = '1.0'
61 55
62 56 # ---------------- IMPORTANT ----------------------
63 57 # If we deploy the app into a subdir name "grader", be sure to do "rake assets:precompile RAILS_RELATIVE_URL_ROOT=/grader"
64 58 # moreover, using the following line instead also known to works
65 59 #config.action_controller.relative_url_root = '/grader'
66 60
67 61 #font path
68 62 config.assets.paths << "#{Rails}/vendor/assets/fonts"
69 63
70 64 config.assets.precompile += ['announcement_refresh.js','effects.js','site_update.js']
71 65 config.assets.precompile += ['local_jquery.js','tablesorter-theme.cafe.css']
72 66 %w( announcements submissions configurations contests contest_management graders heartbeat
73 67 login main messages problems report site sites sources tasks
74 68 test user_admin users ).each do |controller|
75 69 config.assets.precompile += ["#{controller}.js", "#{controller}.css"]
76 70 end
77 71 end
78 72 end
You need to be logged in to leave comments. Login now