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

r733:06d038074b56 - - 4 files changed: 4 inserted, 2 deleted

@@ -94,193 +94,193
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 p = 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 130 def toggle_test
131 131 @problem = Problem.find(params[:id])
132 132 @problem.update_attributes(test_allowed: !(@problem.test_allowed?) )
133 133 respond_to do |format|
134 134 format.js { }
135 135 end
136 136 end
137 137
138 138 def toggle_view_testcase
139 139 @problem = Problem.find(params[:id])
140 140 @problem.update_attributes(view_testcase: !(@problem.view_testcase?) )
141 141 respond_to do |format|
142 142 format.js { }
143 143 end
144 144 end
145 145
146 146 def turn_all_off
147 147 Problem.available.all.each do |problem|
148 148 problem.available = false
149 149 problem.save
150 150 end
151 151 redirect_to action: :index
152 152 end
153 153
154 154 def turn_all_on
155 155 Problem.where.not(available: true).each do |problem|
156 156 problem.available = true
157 157 problem.save
158 158 end
159 159 redirect_to action: :index
160 160 end
161 161
162 162 def stat
163 163 @problem = Problem.find(params[:id])
164 164 unless @problem.available or session[:admin]
165 165 redirect_to :controller => 'main', :action => 'list'
166 166 return
167 167 end
168 168 @submissions = Submission.includes(:user).includes(:language).where(problem_id: params[:id]).order(:user_id,:id)
169 169
170 170 #stat summary
171 171 range =65
172 172 @histogram = { data: Array.new(range,0), summary: {} }
173 173 user = Hash.new(0)
174 174 @submissions.find_each do |sub|
175 175 d = (DateTime.now.in_time_zone - sub.submitted_at) / 24 / 60 / 60
176 176 @histogram[:data][d.to_i] += 1 if d < range
177 177 user[sub.user_id] = [user[sub.user_id], ((sub.try(:points) || 0) >= @problem.full_score) ? 1 : 0].max
178 178 end
179 179 @histogram[:summary][:max] = [@histogram[:data].max,1].max
180 180
181 181 @summary = { attempt: user.count, solve: 0 }
182 182 user.each_value { |v| @summary[:solve] += 1 if v == 1 }
183 183 end
184 184
185 185 def manage
186 186 @problems = Problem.order(date_added: :desc)
187 187 end
188 188
189 189 def do_manage
190 - if params.has_key? 'change_date_added'
190 + if params.has_key? 'change_date_added' and params[:date_added].strip.empty? == false
191 191 change_date_added
192 192 elsif params.has_key? 'add_to_contest'
193 193 add_to_contest
194 194 elsif params.has_key? 'enable_problem'
195 195 set_available(true)
196 196 elsif params.has_key? 'disable_problem'
197 197 set_available(false)
198 198 elsif params.has_key? 'add_group'
199 199 group = Group.find(params[:group_id])
200 200 ok = []
201 201 failed = []
202 202 get_problems_from_params.each do |p|
203 203 begin
204 204 group.problems << p
205 205 ok << p.full_name
206 206 rescue => e
207 207 failed << p.full_name
208 208 end
209 209 end
210 210 flash[:success] = "The following problems are added to the group #{group.name}: " + ok.join(', ') if ok.count > 0
211 211 flash[:alert] = "The following problems are already in the group #{group.name}: " + failed.join(', ') if failed.count > 0
212 212 elsif params.has_key? 'add_tags'
213 213 get_problems_from_params.each do |p|
214 214 p.tag_ids += params[:tag_ids]
215 215 end
216 216 end
217 217
218 218 redirect_to :action => 'manage'
219 219 end
220 220
221 221 def import
222 222 @allow_test_pair_import = allow_test_pair_import?
223 223 end
224 224
225 225 def do_import
226 226 old_problem = Problem.find_by_name(params[:name])
227 227 if !allow_test_pair_import? and params.has_key? :import_to_db
228 228 params.delete :import_to_db
229 229 end
230 230 @problem, import_log = Problem.create_from_import_form_params(params,
231 231 old_problem)
232 232
233 233 if !@problem.errors.empty?
234 234 render :action => 'import' and return
235 235 end
236 236
237 237 if old_problem!=nil
238 238 flash[:notice] = "The test data has been replaced for problem #{@problem.name}"
239 239 end
240 240 @log = import_log
241 241 end
242 242
243 243 def remove_contest
244 244 problem = Problem.find(params[:id])
245 245 contest = Contest.find(params[:contest_id])
246 246 if problem!=nil and contest!=nil
247 247 problem.contests.delete(contest)
248 248 end
249 249 redirect_to :action => 'manage'
250 250 end
251 251
252 252 ##################################
253 253 protected
254 254
255 255 def allow_test_pair_import?
256 256 if defined? ALLOW_TEST_PAIR_IMPORT
257 257 return ALLOW_TEST_PAIR_IMPORT
258 258 else
259 259 return false
260 260 end
261 261 end
262 262
263 263 def change_date_added
264 264 problems = get_problems_from_params
265 265 date = Date.parse(params[:date_added])
266 266 problems.each do |p|
267 267 p.date_added = date
268 268 p.save
269 269 end
270 270 end
271 271
272 272 def add_to_contest
273 273 problems = get_problems_from_params
274 274 contest = Contest.find(params[:contest][:id])
275 275 if contest!=nil and contest.enabled
276 276 problems.each do |p|
277 277 p.contests << contest
278 278 end
279 279 end
280 280 end
281 281
282 282 def set_available(avail)
283 283 problems = get_problems_from_params
284 284 problems.each do |p|
285 285 p.available = avail
286 286 p.save
@@ -1,142 +1,142
1 1 require 'csv'
2 2
3 3 class ReportController < ApplicationController
4 4
5 5 before_filter :authenticate
6 6
7 7 before_filter :admin_authorization, only: [:login_stat,:submission_stat, :stuck, :cheat_report, :cheat_scruntinize, :show_max_score, :current_score]
8 8
9 9 before_filter(only: [:problem_hof]) { |c|
10 10 return false unless authenticate
11 11
12 12 admin_authorization unless GraderConfiguration["right.user_view_submission"]
13 13 }
14 14
15 15 def max_score
16 16 end
17 17
18 18 def current_score
19 19 @problems = Problem.available_problems
20 20 @users = User.includes(:contests).includes(:contest_stat).where(enabled: true)
21 21 @scorearray = calculate_max_score(@problems, @users,0,0,true)
22 22
23 23 #rencer accordingly
24 24 if params[:button] == 'download' then
25 25 csv = gen_csv_from_scorearray(@scorearray,@problems)
26 26 send_data csv, filename: 'max_score.csv'
27 27 else
28 28 #render template: 'user_admin/user_stat'
29 29 render 'current_score'
30 30 end
31 31 end
32 32
33 33 def show_max_score
34 34 #process parameters
35 35 #problems
36 36 @problems = []
37 37 if params[:problem_id]
38 38 params[:problem_id].each do |id|
39 39 next unless id.strip != ""
40 40 pid = Problem.find_by_id(id.to_i)
41 41 @problems << pid if pid
42 42 end
43 43 end
44 44
45 45 #users
46 - @users = if params[:user] == "all" then
46 + @users = if params[:users] == "all" then
47 47 User.includes(:contests).includes(:contest_stat)
48 48 else
49 49 User.includes(:contests).includes(:contest_stat).where(enabled: true)
50 50 end
51 51
52 52 #set up range from param
53 53 @since_id = params.fetch(:from_id, 0).to_i
54 54 @until_id = params.fetch(:to_id, 0).to_i
55 55 @since_id = nil if @since_id == 0
56 56 @until_id = nil if @until_id == 0
57 57
58 58 #calculate the routine
59 59 @scorearray = calculate_max_score(@problems, @users, @since_id, @until_id)
60 60
61 61 #rencer accordingly
62 62 if params[:button] == 'download' then
63 63 csv = gen_csv_from_scorearray(@scorearray,@problems)
64 64 send_data csv, filename: 'max_score.csv'
65 65 else
66 66 #render template: 'user_admin/user_stat'
67 67 render 'max_score'
68 68 end
69 69
70 70 end
71 71
72 72 def score
73 73 if params[:commit] == 'download csv'
74 74 @problems = Problem.all
75 75 else
76 76 @problems = Problem.available_problems
77 77 end
78 78 @users = User.includes(:contests, :contest_stat).where(enabled: true)
79 79 @scorearray = Array.new
80 80 @users.each do |u|
81 81 ustat = Array.new
82 82 ustat[0] = u
83 83 @problems.each do |p|
84 84 sub = Submission.find_last_by_user_and_problem(u.id,p.id)
85 85 if (sub!=nil) and (sub.points!=nil) and p and p.full_score
86 86 ustat << [(sub.points.to_f*100/p.full_score).round, (sub.points>=p.full_score)]
87 87 else
88 88 ustat << [0,false]
89 89 end
90 90 end
91 91 @scorearray << ustat
92 92 end
93 93 if params[:commit] == 'download csv' then
94 94 csv = gen_csv_from_scorearray(@scorearray,@problems)
95 95 send_data csv, filename: 'last_score.csv'
96 96 else
97 97 render template: 'user_admin/user_stat'
98 98 end
99 99
100 100 end
101 101
102 102 def login_stat
103 103 @logins = Array.new
104 104
105 105 date_and_time = '%Y-%m-%d %H:%M'
106 106 begin
107 107 md = params[:since_datetime].match(/(\d+)-(\d+)-(\d+) (\d+):(\d+)/)
108 108 @since_time = Time.zone.local(md[1].to_i,md[2].to_i,md[3].to_i,md[4].to_i,md[5].to_i)
109 109 rescue
110 110 @since_time = DateTime.new(1000,1,1)
111 111 end
112 112 begin
113 113 md = params[:until_datetime].match(/(\d+)-(\d+)-(\d+) (\d+):(\d+)/)
114 114 @until_time = Time.zone.local(md[1].to_i,md[2].to_i,md[3].to_i,md[4].to_i,md[5].to_i)
115 115 rescue
116 116 @until_time = DateTime.new(3000,1,1)
117 117 end
118 118
119 119 User.all.each do |user|
120 120 @logins << { id: user.id,
121 121 login: user.login,
122 122 full_name: user.full_name,
123 123 count: Login.where("user_id = ? AND created_at >= ? AND created_at <= ?",
124 124 user.id,@since_time,@until_time)
125 125 .count(:id),
126 126 min: Login.where("user_id = ? AND created_at >= ? AND created_at <= ?",
127 127 user.id,@since_time,@until_time)
128 128 .minimum(:created_at),
129 129 max: Login.where("user_id = ? AND created_at >= ? AND created_at <= ?",
130 130 user.id,@since_time,@until_time)
131 131 .maximum(:created_at),
132 132 ip: Login.where("user_id = ? AND created_at >= ? AND created_at <= ?",
133 133 user.id,@since_time,@until_time)
134 134 .select(:ip_address).uniq
135 135
136 136 }
137 137 end
138 138 end
139 139
140 140 def submission_stat
141 141
142 142 date_and_time = '%Y-%m-%d %H:%M'
@@ -17,102 +17,103
17 17 $('tr input').click( function(e) {
18 18 if (e.shiftKey) {
19 19 stop = parseInt($(this).attr('id').split('-')[2]);
20 20 var orig_stop = stop
21 21 if (typeof start !== 'undefined') {
22 22 if (start > stop) {
23 23 var tmp = start;
24 24 start = stop;
25 25 stop = tmp;
26 26 }
27 27 shiftclick(start,stop,$(this).is(':checked') )
28 28 }
29 29 start = orig_stop
30 30 } else {
31 31 start = parseInt($(this).attr('id').split('-')[2]);
32 32 }
33 33 });
34 34 });
35 35
36 36
37 37 %h1 Manage problems
38 38
39 39 %p= link_to '[Back to problem list]', problems_path
40 40
41 41 = form_tag :action=>'do_manage' do
42 42 .panel.panel-primary
43 43 .panel-heading
44 44 Action
45 45 .panel-body
46 46 .submit-box
47 47 What do you want to do to the selected problem?
48 48 %br/
49 49 (You can shift-click to select a range of problems)
50 50 %ul.form-inline
51 51 %li
52 52 Change "Date added" to
53 53 .input-group.date
54 54 = text_field_tag :date_added, class: 'form-control'
55 55 %span.input-group-addon
56 56 %span.glyphicon.glyphicon-calendar
57 57 -# = select_date Date.current, :prefix => 'date_added'
58 58 &nbsp;&nbsp;&nbsp;
59 59 = submit_tag 'Change', :name => 'change_date_added', class: 'btn btn-primary btn-sm'
60 60 %li
61 61 Set "Available" to
62 62 = submit_tag 'True', :name => 'enable_problem', class: 'btn btn-primary btn-sm'
63 63 = submit_tag 'False', :name => 'disable_problem', class: 'btn btn-primary btn-sm'
64 64
65 65 - if GraderConfiguration.multicontests?
66 66 %li
67 67 Add selected problems to contest
68 68 = select("contest","id",Contest.all.collect {|c| [c.title, c.id]})
69 69 = submit_tag 'Add', :name => 'add_to_contest', class: 'btn btn-primary btn-sm'
70 70 %li
71 71 Add selected problems to user group
72 72 = select_tag "group_id", options_from_collection_for_select( Group.all, 'id','name',params[:group_name]), id: 'group_name',class: 'select2'
73 73 = submit_tag 'Add', name: 'add_group', class: 'btn btn-primary'
74 74 %li
75 75 Add the following tags to the selected problems
76 76 = select_tag "tag_ids", options_from_collection_for_select( Tag.all, 'id','name'), id: 'tags_name',class: 'select2', multiple: true, data: {placeholder: 'Select tags by clicking', width: "200px"}
77 77 = submit_tag 'Add', name: 'add_tags', class: 'btn btn-primary'
78 78
79 79 %table.table.table-hover.datatable
80 80 %thead
81 81 %tr{style: "text-align: left;"}
82 82 %th= check_box_tag 'select_all'
83 83 %th Name
84 84 %th Full name
85 85 %th Tags
86 86 %th Available
87 87 %th Date added
88 88 - if GraderConfiguration.multicontests?
89 89 %th Contests
90 90
91 91 %tbody
92 92 - num = 0
93 93 - for problem in @problems
94 94 - num += 1
95 95 %tr{:id => "row-prob-#{problem.id}", :name=> "prob-#{problem.id}"}
96 96 %td= check_box_tag "prob-#{problem.id}-#{num}"
97 97 %td= problem.name
98 98 %td= problem.full_name
99 99 %td
100 100 - problem.tags.each do |t|
101 101 %span.label.label-default= t.name
102 102 %td= problem.available
103 103 %td= problem.date_added
104 104 - if GraderConfiguration.multicontests?
105 105 %td
106 106 - problem.contests.each do |contest|
107 107 = "(#{contest.name} [#{link_to 'x', :action => 'remove_contest', :id => problem.id, :contest_id => contest.id }])"
108 108
109 109 :javascript
110 110 $('.input-group.date').datetimepicker({
111 111 format: 'DD/MMM/YYYY',
112 112 showTodayButton: true,
113 + locale: 'en',
113 114 widgetPositioning: {horizontal: 'auto', vertical: 'bottom'},
114 115
115 116 });
116 117 $('.datatable').DataTable({
117 118 paging: false
118 119 });
@@ -1,36 +1,37
1 1 %h1 Editing site
2 2 = error_messages_for :site
3 3 = form_for(@site) do |f|
4 4 .row
5 5 .col-md-4
6 6 .form-group.field
7 7 = f.label :name, "Name"
8 8 = f.text_field :name, class: 'form-control'
9 9 .form-group.field
10 10 = f.label :password, "Password"
11 11 = f.text_field :password, class: 'form-control'
12 12 .form-group.field
13 13 = f.label :started, "Started"
14 14 = f.check_box :started, class: 'form-control'
15 15 .form-group.field
16 16 = f.label :start_time, "Start time"
17 17 -# = f.datetime_select :start_time, :include_blank => true
18 18 .input-group.date
19 19 = f.text_field :start_time, class:'form-control' , value: (@site.start_time ? @site.start_time.strftime('%d/%b/%Y %H:%M') : '')
20 20 %span.input-group-addon
21 21 %span.glyphicon.glyphicon-calendar
22 22 .actions
23 23 = f.submit "Update", class: 'btn btn-primary'
24 24 .col-md-8
25 25
26 26 = link_to 'Show', @site
27 27 |
28 28 = link_to 'Back', sites_path
29 29
30 30
31 31 :javascript
32 32 $('.input-group.date').datetimepicker({
33 33 format: 'DD/MMM/YYYY HH:mm',
34 + locale: 'en',
34 35 showTodayButton: true,
35 36 });
36 37
You need to be logged in to leave comments. Login now