Description:
only grades users in the contest
Commit status:
[Not Reviewed]
References:
Comments:
0 Commit comments 0 Inline Comments
Unresolved TODOs:
There are no unresolved TODOs
Add another comment

r94:1ba4bf8cd712 - - 1 file changed: 9 inserted, 6 deleted

@@ -15,327 +15,330
15 15
16 16 def clear_stopfile
17 17 if FileTest.exist?(File.dirname(__FILE__) + "/stop.#{Process.pid}")
18 18 system("rm " + File.dirname(__FILE__) + "/stop.#{Process.pid}")
19 19 end
20 20 end
21 21
22 22 def config
23 23 Grader::Configuration.get_instance
24 24 end
25 25
26 26 def log_file_name
27 27 if !File.exists?(config.log_dir)
28 28 raise "Log directory does not exist: #{config.log_dir}"
29 29 end
30 30 config.log_dir +
31 31 "/#{GRADER_ENV}_#{config.grader_mode}.#{Process.pid}"
32 32 end
33 33
34 34 def log(str)
35 35 if config.talkative
36 36 puts str
37 37 end
38 38 if config.logging
39 39 fp = File.open(log_file_name,"a")
40 40 fp.puts("GRADER: #{Time.new.strftime("%H:%M")} #{str}")
41 41 fp.close
42 42 end
43 43 end
44 44
45 45 def display_manual
46 46 puts <<USAGE
47 47 Grader.
48 48 using: (1) grader
49 49 (2) grader environment [mode]
50 50 (3) grader stop [all|pids-list]
51 51 (4) grader --help
52 52 (1) call grader with environment = 'exam', mode = 'queue'
53 53 (2) possible modes are: 'queue', 'prob', 'test_request'
54 54 (3) create stop-file to stop running grader in queue mode
55 55 (4) You are here.
56 56 USAGE
57 57 end
58 58
59 59 def process_options_and_stop_file
60 60 # The list of options are:
61 61 # - stop [all|process ids]
62 62 # -
63 63
64 64 # Process 'help' option
65 65 if (ARGV.length==1) and (/help/.match(ARGV[0]))
66 66 display_manual
67 67 exit(0)
68 68 end
69 69
70 70 # Process 'stop' option.
71 71 if (ARGV.length >= 1) and (ARGV[0]=='stop')
72 72 if ARGV.length==1
73 73 puts "you should specify pid-list or 'all'"
74 74 display_manual
75 75 elsif (ARGV.length==2) and (ARGV[1]=='all')
76 76 stop_grader(:all)
77 77 puts "A global stop file ('stop.all') created."
78 78 puts "You should remove it manually later."
79 79 else
80 80 (1..ARGV.length-1).each do |i|
81 81 stop_grader(ARGV[i])
82 82 end
83 83 puts "stop file(s) created"
84 84 end
85 85 exit(0)
86 86 end
87 87
88 88 # Check stop file.
89 89 if check_stopfile
90 90 puts "Stop file exists. Terminated."
91 91 clear_stopfile
92 92 exit(0)
93 93 end
94 94
95 95 #default options
96 96 options = {
97 97 :mode => 'queue',
98 98 :environment => 'exam',
99 99 :dry_run => false,
100 100 }
101 101
102 102 # Process mode and environment option
103 103 if ARGV.length >= 1
104 104 options[:environment] = ARGV.shift
105 105 if ARGV.length >=1
106 106 options[:mode] = ARGV.shift
107 107 end
108 108 end
109 109
110 110 options[:dry_run] = (ARGV.delete('--dry') != nil)
111 - if options[:dry_run] and (not options[:mode] == 'prob')
112 - puts "Dry run currently works only for 'prob' mode."
111 + if options[:dry_run] and (not ['prob','contest'].include? options[:mode])
112 + puts "Dry run currently works only for 'prob' or 'contest' modes."
113 113 exit(0)
114 114 end
115 115
116 116 options[:report] = (ARGV.delete('--report') != nil)
117 117 if options[:report] and (not ['prob','contest'].include? options[:mode])
118 - puts "Report currently works only for 'prob' mode."
118 + puts "Report currently works only for 'prob' or 'contest' modes."
119 119 exit(0)
120 120 end
121 121
122 122 return options
123 123 end
124 124
125 125 class ResultCollector
126 126 def initialize
127 127 @results = {}
128 128 @problems = {}
129 129 @users = {}
130 130 end
131 131
132 132 def save(user, problem, grading_result)
133 133 if not @problems.has_key? problem.id
134 134 @problems[problem.id] = problem
135 135 end
136 136 if not @users.has_key? user.id
137 137 @users[user.id] = user
138 138 end
139 139 @results[[user.id, problem.id]] = grading_result
140 140 end
141 141
142 142 def print_report_by_user
143 143 puts "---------------------"
144 144 puts " REPORT"
145 145 puts "---------------------"
146 146
147 - print "login"
147 + print "login,email"
148 148 @problems.each_value do |problem|
149 149 print ",#{problem.name}"
150 150 end
151 151 print "\n"
152 152
153 153 @users.each_value do |user|
154 - print "#{user.login}"
154 + print "#{user.login},#{user.email}"
155 155 @problems.each_value do |problem|
156 156 if @results.has_key? [user.id, problem.id]
157 157 print ",#{@results[[user.id,problem.id]][:points]}"
158 158 else
159 159 print ","
160 160 end
161 161 end
162 162 print "\n"
163 163 end
164 164 end
165 165 end
166 166
167 167 #########################################
168 168 # main program
169 169 #########################################
170 170
171 171 options = process_options_and_stop_file
172 172 GRADER_ENV = options[:environment]
173 173 grader_mode = options[:mode]
174 174 dry_run = options[:dry_run]
175 175
176 176 puts "environment: #{GRADER_ENV}"
177 177 require File.join(File.dirname(__FILE__),'config/environment')
178 178
179 179 # add grader_mode to config
180 180 # this is needed because method log needs it. TODO: clean this up
181 181 class << config
182 182 attr_accessor :grader_mode
183 183 end
184 184 config.grader_mode = grader_mode
185 185
186 186 # reading rails environment
187 187 log 'Reading rails environment'
188 188
189 189 RAILS_ENV = config.rails_env
190 190 require RAILS_ROOT + '/config/environment'
191 191
192 192 # register grader process
193 193 if config.report_grader
194 194 grader_proc = GraderProcess.register(config.grader_hostname,
195 195 Process.pid,
196 196 grader_mode)
197 197 else
198 198 grader_proc = nil
199 199 end
200 200
201 201 #set loggin environment
202 202 ENV['GRADER_LOGGING'] = log_file_name
203 203
204 204 # register exit handler to report inactive, and terminated
205 205 at_exit do
206 206 if grader_proc!=nil
207 207 grader_proc.report_inactive
208 208 grader_proc.terminate
209 209 end
210 210 end
211 211
212 212 #
213 213 # MAIN LOOP
214 214 #
215 215
216 216 case grader_mode
217 217 when "queue", "test_request"
218 218 log "Grader: #{grader_mode}"
219 219 if grader_mode=="queue"
220 220 engine = Grader::Engine.new
221 221 else
222 222 engine = Grader::Engine.new(:room_maker => Grader::TestRequestRoomMaker.new,
223 223 :reporter => Grader::TestRequestReporter.new)
224 224 end
225 225
226 226 runner = Grader::Runner.new(engine, grader_proc)
227 227 while true
228 228
229 229 if check_stopfile # created by calling grader stop
230 230 clear_stopfile
231 231 log "stopped (with stop file)"
232 232 break
233 233 end
234 234
235 235 if grader_mode=="queue"
236 236 task = runner.grade_oldest_task
237 237 else
238 238 task = runner.grade_oldest_test_request
239 239 end
240 240 if task==nil
241 241 sleep(1)
242 242 end
243 243 end
244 244
245 245 when "prob"
246 246 if options[:report]
247 247 result_collector = ResultCollector.new
248 248 else
249 249 result_collector = nil
250 250 end
251 251
252 252 if options[:dry_run]
253 253 puts "Running in dry mode"
254 254 end
255 255
256 256 prob_reporter = Grader::SubmissionReporter.new(:dry_run => dry_run,
257 257 :result_collector => result_collector)
258 258 engine = Grader::Engine.new(:reporter => prob_reporter)
259 259 runner = Grader::Runner.new(engine, grader_proc)
260 260
261 261 grader_proc.report_active if grader_proc!=nil
262 262
263 263 ARGV.each do |prob_name|
264 264 prob = Problem.find_by_name(prob_name)
265 265 if prob==nil
266 266 puts "cannot find problem: #{prob_name}"
267 267 else
268 268 runner.grade_problem(prob)
269 269 end
270 270 end
271 271
272 272 if options[:report]
273 273 result_collector.print_report_by_user
274 274 end
275 275
276 276 when "contest"
277 277 # always use dry run when grading during contest
278 278 contest_name = ARGV.shift
279 279
280 280 options[:dry_run] = true
281 281
282 282 contest = Contest.find_by_name(contest_name)
283 283 if contest==nil
284 284 puts "cannot find contest: #{contest_name}"
285 285 exit(0)
286 286 end
287 287
288 288 if options[:report]
289 289 result_collector = ResultCollector.new
290 290 else
291 291 result_collector = nil
292 292 end
293 293
294 294 if options[:dry_run]
295 295 puts "Running in dry mode"
296 296 end
297 297
298 298 prob_reporter = Grader::SubmissionReporter.new(:dry_run => dry_run,
299 299 :result_collector => result_collector)
300 300 engine = Grader::Engine.new(:reporter => prob_reporter)
301 301 runner = Grader::Runner.new(engine, grader_proc)
302 302
303 303 grader_proc.report_active if grader_proc!=nil
304 304
305 305 contest.problems.each do |problem|
306 306 puts "Grading: #{problem.name}"
307 307 runner.grade_problem(problem,
308 - :user_conditions => lambda {|u| u.contest_finished?})
308 + :user_conditions => lambda do |u|
309 + u.contest_finished? and
310 + u.contest_ids.include?(contest.id)
311 + end)
309 312 end
310 313
311 314 if options[:report]
312 315 result_collector.print_report_by_user
313 316 end
314 317
315 318 when "sub"
316 319 engine = Grader::Engine.new
317 320 runner = Grader::Runner.new(engine, grader_proc)
318 321
319 322 grader_proc.report_active if grader_proc!=nil
320 323
321 324 ARGV.each do |sub_id|
322 325 puts "Grading #{sub_id}"
323 326 begin
324 327 submission = Submission.find(sub_id.to_i)
325 328 rescue ActiveRecord::RecordNotFound
326 329 puts "Record not found"
327 330 submission = nil
328 331 end
329 332
330 333 if submission!=nil
331 334 runner.grade_submission(submission)
332 335 end
333 336 end
334 337
335 338
336 339
337 340 else
338 341 display_manual
339 342 exit(0)
340 343 end
341 344
You need to be logged in to leave comments. Login now