Description:
- add problem manage toggle test interface - remove old erb file
Commit status:
[Not Reviewed]
References:
Comments:
0 Commit comments 0 Inline Comments
Unresolved TODOs:
There are no unresolved TODOs
Add another comment

r569:47e6e54a036a - - 6 files changed: 28 inserted, 171 deleted

@@ -1,274 +1,282
1 1 class ProblemsController < ApplicationController
2 2
3 3 before_filter :authenticate, :authorization
4 4
5 5 in_place_edit_for :problem, :name
6 6 in_place_edit_for :problem, :full_name
7 7 in_place_edit_for :problem, :full_score
8 8
9 9 def index
10 10 @problems = Problem.find(:all, :order => 'date_added DESC')
11 11 end
12 12
13 13 # GETs should be safe (see http://www.w3.org/2001/tag/doc/whenToUseGet.html)
14 14 verify :method => :post, :only => [ :destroy,
15 15 :create, :quick_create,
16 16 :do_manage,
17 17 :do_import,
18 18 :update ],
19 19 :redirect_to => { :action => :index }
20 20
21 21 def show
22 22 @problem = Problem.find(params[:id])
23 23 end
24 24
25 25 def new
26 26 @problem = Problem.new
27 27 @description = nil
28 28 end
29 29
30 30 def create
31 31 @problem = Problem.new(params[:problem])
32 32 @description = Description.new(params[:description])
33 33 if @description.body!=''
34 34 if !@description.save
35 35 render :action => new and return
36 36 end
37 37 else
38 38 @description = nil
39 39 end
40 40 @problem.description = @description
41 41 if @problem.save
42 42 flash[:notice] = 'Problem was successfully created.'
43 43 redirect_to action: :index
44 44 else
45 45 render :action => 'new'
46 46 end
47 47 end
48 48
49 49 def quick_create
50 50 @problem = Problem.new(params[:problem])
51 51 @problem.full_name = @problem.name if @problem.full_name == ''
52 52 @problem.full_score = 100
53 53 @problem.available = false
54 54 @problem.test_allowed = true
55 55 @problem.output_only = false
56 56 @problem.date_added = Time.new
57 57 if @problem.save
58 58 flash[:notice] = 'Problem was successfully created.'
59 59 redirect_to action: :index
60 60 else
61 61 flash[:notice] = 'Error saving problem'
62 62 redirect_to action: :index
63 63 end
64 64 end
65 65
66 66 def edit
67 67 @problem = Problem.find(params[:id])
68 68 @description = @problem.description
69 69 end
70 70
71 71 def update
72 72 @problem = Problem.find(params[:id])
73 73 @description = @problem.description
74 74 if @description == nil and params[:description][:body]!=''
75 75 @description = Description.new(params[:description])
76 76 if !@description.save
77 77 flash[:notice] = 'Error saving description'
78 78 render :action => 'edit' and return
79 79 end
80 80 @problem.description = @description
81 81 elsif @description!=nil
82 82 if !@description.update_attributes(params[:description])
83 83 flash[:notice] = 'Error saving description'
84 84 render :action => 'edit' and return
85 85 end
86 86 end
87 87 if params[:file] and params[:file].content_type != 'application/pdf'
88 88 flash[:notice] = 'Error: Uploaded file is not PDF'
89 89 render :action => 'edit' and return
90 90 end
91 91 if @problem.update_attributes(params[:problem])
92 92 flash[:notice] = 'Problem was successfully updated.'
93 93 unless params[:file] == nil or params[:file] == ''
94 94 flash[:notice] = 'Problem was successfully updated and a new PDF file is uploaded.'
95 95 out_dirname = "#{Problem.download_file_basedir}/#{@problem.id}"
96 96 if not FileTest.exists? out_dirname
97 97 Dir.mkdir out_dirname
98 98 end
99 99
100 100 out_filename = "#{out_dirname}/#{@problem.name}.pdf"
101 101 if FileTest.exists? out_filename
102 102 File.delete out_filename
103 103 end
104 104
105 105 File.open(out_filename,"wb") do |file|
106 106 file.write(params[:file].read)
107 107 end
108 108 @problem.description_filename = "#{@problem.name}.pdf"
109 109 @problem.save
110 110 end
111 111 redirect_to :action => 'show', :id => @problem
112 112 else
113 113 render :action => 'edit'
114 114 end
115 115 end
116 116
117 117 def destroy
118 118 Problem.find(params[:id]).destroy
119 119 redirect_to action: :index
120 120 end
121 121
122 122 def toggle
123 123 @problem = Problem.find(params[:id])
124 124 @problem.update_attributes(available: !(@problem.available) )
125 125 respond_to do |format|
126 126 format.js { }
127 127 end
128 128 end
129 129
130 + def toggle_test
131 + @problem = Problem.find(params[:id])
132 + @problem.update_attributes(test_allowed: !(@problem.test_allowed?) )
133 + respond_to do |format|
134 + format.js { }
135 + end
136 + end
137 +
130 138 def turn_all_off
131 139 Problem.find(:all,
132 140 :conditions => "available = 1").each do |problem|
133 141 problem.available = false
134 142 problem.save
135 143 end
136 144 redirect_to action: :index
137 145 end
138 146
139 147 def turn_all_on
140 148 Problem.find(:all,
141 149 :conditions => "available = 0").each do |problem|
142 150 problem.available = true
143 151 problem.save
144 152 end
145 153 redirect_to action: :index
146 154 end
147 155
148 156 def stat
149 157 @problem = Problem.find(params[:id])
150 158 unless @problem.available or session[:admin]
151 159 redirect_to :controller => 'main', :action => 'list'
152 160 return
153 161 end
154 162 @submissions = Submission.includes(:user).where(problem_id: params[:id]).order(:user_id,:id)
155 163
156 164 #stat summary
157 165 range =65
158 166 @histogram = { data: Array.new(range,0), summary: {} }
159 167 user = Hash.new(0)
160 168 @submissions.find_each do |sub|
161 169 d = (DateTime.now.in_time_zone - sub.submitted_at) / 24 / 60 / 60
162 170 @histogram[:data][d.to_i] += 1 if d < range
163 171 user[sub.user_id] = [user[sub.user_id], ((sub.try(:points) || 0) >= @problem.full_score) ? 1 : 0].max
164 172 end
165 173 @histogram[:summary][:max] = [@histogram[:data].max,1].max
166 174
167 175 @summary = { attempt: user.count, solve: 0 }
168 176 user.each_value { |v| @summary[:solve] += 1 if v == 1 }
169 177 end
170 178
171 179 def manage
172 180 @problems = Problem.find(:all, :order => 'date_added DESC')
173 181 end
174 182
175 183 def do_manage
176 184 if params.has_key? 'change_date_added'
177 185 change_date_added
178 186 elsif params.has_key? 'add_to_contest'
179 187 add_to_contest
180 188 elsif params.has_key? 'enable_problem'
181 189 set_available(true)
182 190 elsif params.has_key? 'disable_problem'
183 191 set_available(false)
184 192 end
185 193 redirect_to :action => 'manage'
186 194 end
187 195
188 196 def import
189 197 @allow_test_pair_import = allow_test_pair_import?
190 198 end
191 199
192 200 def do_import
193 201 old_problem = Problem.find_by_name(params[:name])
194 202 if !allow_test_pair_import? and params.has_key? :import_to_db
195 203 params.delete :import_to_db
196 204 end
197 205 @problem, import_log = Problem.create_from_import_form_params(params,
198 206 old_problem)
199 207
200 208 if !@problem.errors.empty?
201 209 render :action => 'import' and return
202 210 end
203 211
204 212 if old_problem!=nil
205 213 flash[:notice] = "The test data has been replaced for problem #{@problem.name}"
206 214 end
207 215 @log = import_log
208 216 end
209 217
210 218 def remove_contest
211 219 problem = Problem.find(params[:id])
212 220 contest = Contest.find(params[:contest_id])
213 221 if problem!=nil and contest!=nil
214 222 problem.contests.delete(contest)
215 223 end
216 224 redirect_to :action => 'manage'
217 225 end
218 226
219 227 ##################################
220 228 protected
221 229
222 230 def allow_test_pair_import?
223 231 if defined? ALLOW_TEST_PAIR_IMPORT
224 232 return ALLOW_TEST_PAIR_IMPORT
225 233 else
226 234 return false
227 235 end
228 236 end
229 237
230 238 def change_date_added
231 239 problems = get_problems_from_params
232 240 year = params[:date_added][:year].to_i
233 241 month = params[:date_added][:month].to_i
234 242 day = params[:date_added][:day].to_i
235 243 date = Date.new(year,month,day)
236 244 problems.each do |p|
237 245 p.date_added = date
238 246 p.save
239 247 end
240 248 end
241 249
242 250 def add_to_contest
243 251 problems = get_problems_from_params
244 252 contest = Contest.find(params[:contest][:id])
245 253 if contest!=nil and contest.enabled
246 254 problems.each do |p|
247 255 p.contests << contest
248 256 end
249 257 end
250 258 end
251 259
252 260 def set_available(avail)
253 261 problems = get_problems_from_params
254 262 problems.each do |p|
255 263 p.available = avail
256 264 p.save
257 265 end
258 266 end
259 267
260 268 def get_problems_from_params
261 269 problems = []
262 270 params.keys.each do |k|
263 271 if k.index('prob-')==0
264 272 name, id, order = k.split('-')
265 273 problems << Problem.find(id)
266 274 end
267 275 end
268 276 problems
269 277 end
270 278
271 279 def get_problems_stat
272 280 end
273 281
274 282 end
@@ -1,70 +1,73
1 1 %header.navbar.navbar-default.navbar-fixed-top
2 2 %nav
3 3 .container-fluid
4 4 .navbar-header
5 5 %a.navbar-brand{href: main_list_path}
6 6 %span.glyphicon.glyphicon-home
7 7 MAIN
8 8 .collapse.navbar-collapse
9 9 %ul.nav.navbar-nav
10 10 - if (@current_user!=nil) and (GraderConfiguration.show_tasks_to?(@current_user))
11 11 //= add_menu("#{I18n.t 'menu.tasks'}", 'tasks', 'list')
12 12 %li.dropdown
13 13 %a.dropdown-toggle{href: '#', data: {toggle:'dropdown'}, aria: {haspopup:"true", expanded:"false"}, role: "button"}
14 14 = "#{I18n.t 'menu.submissions'}"
15 15 %span.caret
16 16 %ul.dropdown-menu
17 17 = add_menu("View", 'main', 'submission')
18 18 = add_menu("Self Test", 'test', 'index')
19 19 - if GraderConfiguration['right.user_hall_of_fame']
20 20 = add_menu("#{I18n.t 'menu.hall_of_fame'}", 'report', 'problem_hof')
21 21 - if (@current_user!=nil) and (session[:admin])
22 22 %li.dropdown
23 23 %a.dropdown-toggle{href: '#', data: {toggle:'dropdown'}, aria: {haspopup:"true", expanded:"false"}, role: "button"}
24 24 Manage
25 25 %span.caret
26 26 %ul.dropdown-menu
27 27 = add_menu( 'Announcements', 'announcements', 'index')
28 28 = add_menu( 'Problems', 'problems', 'index')
29 29 = add_menu( 'Users', 'user_admin', 'index')
30 30 = add_menu( 'Graders', 'graders', 'list')
31 31 = add_menu( 'Message ', 'messages', 'console')
32 32 %li.divider{role: 'separator'}
33 33 = add_menu( 'System config', 'configurations', 'index')
34 34 %li.divider{role: 'separator'}
35 35 = add_menu( 'Sites', 'sites', 'index')
36 36 = add_menu( 'Contests', 'contest_management', 'index')
37 37 %li.dropdown
38 38 %a.dropdown-toggle{href: '#', data: {toggle:'dropdown'}, aria: {haspopup:"true", expanded:"false"}, role: "button"}
39 39 Report
40 40 %span.caret
41 41 %ul.dropdown-menu
42 42 = add_menu( 'Results', 'user_admin', 'user_stat')
43 43 = add_menu( 'Report', 'report', 'multiple_login')
44 - %button.navbar-btn.btn.btn-default.btn-warning
45 - hahaha
46 -
44 + - if (ungraded = Submission.where('graded_at is null').where('submitted_at < ?', 1.minutes.ago).count) > 0
45 + =link_to "#{ungraded} backlogs!",
46 + grader_list_path,
47 + class: 'navbar-btn btn btn-default btn-warning', data: {toggle: 'tooltip'},title: 'Number of ungraded submission'
48 + =link_to 'Contest Mode, time remain: 00:20:33',grader_list_path,
49 + class: 'navbar-btn btn btn-primary'
47 50
48 51 %ul.nav.navbar-nav.navbar-right
49 52 = add_menu("#{content_tag(:span,'',class: 'glyphicon glyphicon-question-sign')}".html_safe, 'main', 'help')
50 53 = add_menu("#{content_tag(:span,'',class: 'glyphicon glyphicon-comment')}".html_safe, 'messages', 'list', {title: I18n.t('menu.messages'), data: {toggle: 'tooltip'}})
51 54 - if GraderConfiguration['system.user_setting_enabled']
52 55 = add_menu("#{content_tag(:span,'',class: 'glyphicon glyphicon-cog')}".html_safe, 'users', 'index', {title: I18n.t('menu.settings'), data: {toggle: 'tooltip'}})
53 56 = add_menu("#{content_tag(:span,'',class: 'glyphicon glyphicon-log-out')} #{@current_user.full_name}".html_safe, 'main', 'login', {title: I18n.t('menu.log_out'), data: {toggle: 'tooltip'}})
54 57
55 58 /
56 59 - if (@current_user!=nil) and (session[:admin])
57 60 %nav.navbar.navbar-fixed-top.navbar-inverse.secondnavbar
58 61 .container-fluid
59 62 .collapse.navbar-collapse
60 63 %ul.nav.navbar-nav
61 64 = add_menu( '[Announcements]', 'announcements', 'index')
62 65 = add_menu( '[Msg console]', 'messages', 'console')
63 66 = add_menu( '[Problems]', 'problems', 'index')
64 67 = add_menu( '[Users]', 'user_admin', 'index')
65 68 = add_menu( '[Results]', 'user_admin', 'user_stat')
66 69 = add_menu( '[Report]', 'report', 'multiple_login')
67 70 = add_menu( '[Graders]', 'graders', 'list')
68 71 = add_menu( '[Contests]', 'contest_management', 'index')
69 72 = add_menu( '[Sites]', 'sites', 'index')
70 73 = add_menu( '[System config]', 'configurations', 'index')
@@ -1,47 +1,50
1 1 - content_for :head do
2 2 = stylesheet_link_tag 'problems'
3 3 %h1 Listing problems
4 4 %p
5 5 = link_to 'New problem', new_problem_path, class: 'btn btn-default btn-sm'
6 6 = link_to 'Manage problems', { action: 'manage'}, class: 'btn btn-default btn-sm'
7 7 = link_to 'Import problems', {:action => 'import'}, class: 'btn btn-default btn-sm'
8 8 = link_to 'Turn off all problems', {:action => 'turn_all_off'}, class: 'btn btn-default btn-sm'
9 9 = link_to 'Turn on all problems', {:action => 'turn_all_on'}, class: 'btn btn-default btn-sm'
10 10 .submitbox
11 11 = form_tag :action => 'quick_create' do
12 12 %b Quick New:
13 13 %label{:for => "problem_name"} Name
14 14 = text_field 'problem', 'name'
15 15 |
16 16 %label{:for => "problem_full_name"} Full name
17 17 = text_field 'problem', 'full_name'
18 18 = submit_tag "Create"
19 19 %table.table.table-condense.table-hover
20 20 %thead
21 21 %th Name
22 22 %th Full name
23 - %th Full score
23 + %th.text-right Full score
24 24 %th Date added
25 - %th Avail?
26 - %th Test?
25 + %th.text-center
26 + Avail?
27 + %sup{class: 'text-primary',data: {toggle: 'tooltip'}, title: 'Let user submits to this problem?' } [?]
28 + %th.text-center
29 + Test?
30 + %sup{class: 'text-primary',data: {toggle: 'tooltip'}, title: 'Let user uses test interface on this problem?' } [?]
27 31 - if GraderConfiguration.multicontests?
28 32 %th Contests
29 33 - for problem in @problems
30 34 %tr{:class => "#{(problem.available) ? "success" : "danger"}", :id => "prob-#{problem.id}", :name => "prob-#{problem.id}"}
31 35 - @problem=problem
32 36 %td= in_place_editor_field :problem, :name, {}, :rows=>1
33 37 %td= in_place_editor_field :problem, :full_name, {}, :rows=>1
34 - %td= in_place_editor_field :problem, :full_score, {}, :rows=>1
38 + %td.text-right= in_place_editor_field :problem, :full_score, {}, :rows=>1
35 39 %td= problem.date_added
36 - %td= toggle_button(@problem.available?, url_for(controller: :problems, action: :toggle, id: @problem), "problem-avail-#{@problem.id}")
37 - //%td{}= link_to (@problem.available? ? "Yes" : "No"), url_for(controller: :problems, action: :toggle, id: @problem), { class: "btn btn-block btn-sm btn-#{(@problem.available? ? 'success' : 'default')} ajax-toggle", id: "problem-avail-#{@problem.id}", data: {remote: true, method: 'post' } }
38 - %td= problem.test_allowed
40 + %td= toggle_button(@problem.available?, toggle_problem_url(@problem), "problem-avail-#{@problem.id}")
41 + %td= toggle_button(@problem.test_allowed?, toggle_test_problem_url(@problem), "problem-test-#{@problem.id}")
39 42 - if GraderConfiguration.multicontests?
40 43 %td
41 44 = problem.contests.collect { |c| c.name }.join(', ')
42 45 %td= link_to 'Stat', {:action => 'stat', :id => problem.id}, class: 'btn btn-info btn-xs btn-block'
43 46 %td= link_to 'Show', {:action => 'show', :id => problem}, class: 'btn btn-info btn-xs btn-block'
44 47 %td= link_to 'Edit', {:action => 'edit', :id => problem}, class: 'btn btn-info btn-xs btn-block'
45 48 %td= link_to 'Destroy', { :action => 'destroy', :id => problem }, :confirm => 'Are you sure?', :method => :post, class: 'btn btn-danger btn-xs btn-block'
46 49 %br/
47 50 = link_to '[New problem]', :action => 'new'
@@ -1,63 +1,61
1 1 CafeGrader::Application.routes.draw do
2 2 get "sources/direct_edit"
3 3
4 4 root :to => 'main#login'
5 5
6 -
7 6 resources :contests
8 7
9 8 resources :sites
10 9
11 10 resources :announcements do
12 11 member do
13 12 get 'toggle','toggle_front'
14 13 end
15 14 end
16 15
17 -
18 16 resources :problems do
19 17 member do
20 18 get 'toggle'
19 + get 'toggle_test'
21 20 end
22 21 collection do
23 22 get 'turn_all_off'
24 23 get 'turn_all_on'
25 24 get 'import'
26 25 get 'manage'
27 26 end
28 27 end
29 28
30 29 resources :grader_configuration, controller: 'configurations'
31 30
32 31 resources :users do
33 32 member do
34 33 get 'toggle_activate', 'toggle_enable'
35 34 end
36 35 end
37 36
38 - #resources :sources do
39 - # collection do
40 - # end
41 - #end
42 37 get 'sources/direct_edit/:pid', to: 'sources#direct_edit', as: 'direct_edit'
43 38 get 'sources/direct_edit_submission/:sid', to: 'sources#direct_edit_submission', as: 'direct_edit_submission'
44 39
45 40
46 41 match 'tasks/view/:file.:ext' => 'tasks#view'
47 42 match 'tasks/download/:id/:file.:ext' => 'tasks#download'
48 43 match 'heartbeat/:id/edit' => 'heartbeat#edit'
49 44
50 45 #main
51 46 get "main/list"
52 47 get 'main/submission(/:id)', to: 'main#submission', as: 'main_submission'
53 48
54 49 #report
55 50 get 'report/problem_hof(/:id)', to: 'report#problem_hof', as: 'report_problem_hof'
56 51 get "report/login"
57 52
53 + #grader
54 + get 'graders/list', to: 'graders#list', as: 'grader_list'
55 +
58 56 # See how all your routes lay out with "rake routes"
59 57
60 58 # This is a legacy wild controller route that's not recommended for RESTful applications.
61 59 # Note: This route will make all actions in every controller accessible via GET requests.
62 60 match ':controller(/:action(/:id))(.:format)'
63 61 end
deleted file
deleted file
You need to be logged in to leave comments. Login now