Description:
imports test pairs
Commit status:
[Not Reviewed]
References:
Comments:
0 Commit comments 0 Inline Comments
Unresolved TODOs:
There are no unresolved TODOs
Add another comment

r210:0c551aa1f64a - - 4 files changed: 77 inserted, 35 deleted

@@ -147,27 +147,23
147 end
147 end
148
148
149 def import
149 def import
150 end
150 end
151
151
152 def do_import
152 def do_import
153 - @problem, import_log = Problem.new_from_import_form_params(params)
153 + old_problem = Problem.find_by_name(params[:name])
154 + @problem, import_log = Problem.create_from_import_form_params(params,
155 + old_problem)
154
156
155 if @problem.errors.length != 0
157 if @problem.errors.length != 0
156 render :action => 'import' and return
158 render :action => 'import' and return
157 end
159 end
158
160
159 - old_problem = Problem.find_by_name(@problem.name)
160 if old_problem!=nil
161 if old_problem!=nil
161 - old_problem.full_name = @problem.full_name
162 - @problem = old_problem
163 -
164 flash[:notice] = "The test data has been replaced for problem #{@problem.name}"
162 flash[:notice] = "The test data has been replaced for problem #{@problem.name}"
165 end
163 end
166 -
167 - @problem.save
168 @log = import_log
164 @log = import_log
169 end
165 end
170
166
171 ##################################
167 ##################################
172 protected
168 protected
173
169
@@ -1,44 +1,51
1 class Problem < ActiveRecord::Base
1 class Problem < ActiveRecord::Base
2
2
3 belongs_to :description
3 belongs_to :description
4 - has_many :test_pairs
4 + has_many :test_pairs, :dependent => :delete_all
5
5
6 validates_presence_of :name
6 validates_presence_of :name
7 validates_format_of :name, :with => /^\w+$/
7 validates_format_of :name, :with => /^\w+$/
8 validates_presence_of :full_name
8 validates_presence_of :full_name
9
9
10 DEFAULT_TIME_LIMIT = 1
10 DEFAULT_TIME_LIMIT = 1
11 DEFAULT_MEMORY_LIMIT = 32
11 DEFAULT_MEMORY_LIMIT = 32
12
12
13 def self.find_available_problems
13 def self.find_available_problems
14 find(:all, :conditions => {:available => true}, :order => "date_added DESC")
14 find(:all, :conditions => {:available => true}, :order => "date_added DESC")
15 end
15 end
16
16
17 - def self.new_from_import_form_params(params)
17 + def self.create_from_import_form_params(params, old_problem=nil)
18 - problem = Problem.new
18 + problem = old_problem || Problem.new
19 import_params = Problem.extract_params_and_check(params, problem)
19 import_params = Problem.extract_params_and_check(params, problem)
20
20
21 if not problem.valid?
21 if not problem.valid?
22 - return problem
22 + return problem, 'Error importing'
23 - end
24 -
25 - importer = TestdataImporter.new
26 -
27 - if not importer.import_from_file(problem.name,
28 - import_params[:file],
29 - import_params[:time_limit],
30 - import_params[:memory_limit])
31 - problem.errors.add_to_base('Import error.')
32 end
23 end
33
24
34 problem.full_score = 100
25 problem.full_score = 100
35 problem.date_added = Time.new
26 problem.date_added = Time.new
36 problem.test_allowed = true
27 problem.test_allowed = true
37 problem.output_only = false
28 problem.output_only = false
38 problem.available = false
29 problem.available = false
30 +
31 + if not problem.save
32 + return problem, 'Error importing'
33 + end
34 +
35 + import_to_db = params.has_key? :import_to_db
36 +
37 + importer = TestdataImporter.new(problem)
38 +
39 + if not importer.import_from_file(import_params[:file],
40 + import_params[:time_limit],
41 + import_params[:memory_limit],
42 + import_to_db)
43 + problem.errors.add_to_base('Import error.')
44 + end
45 +
39 return problem, importer.log_msg
46 return problem, importer.log_msg
40 end
47 end
41
48
42 protected
49 protected
43
50
44 def self.to_i_or_default(st, default)
51 def self.to_i_or_default(st, default)
@@ -19,13 +19,19
19 %td Full name:
19 %td Full name:
20 %td
20 %td
21 = text_field_tag 'full_name'
21 = text_field_tag 'full_name'
22 %span{:class => 'help'} Leave blank to use the same value as the name above.
22 %span{:class => 'help'} Leave blank to use the same value as the name above.
23 %tr
23 %tr
24 %td Testdata file:
24 %td Testdata file:
25 - %td= file_field_tag 'file'
25 + %td
26 + = file_field_tag 'file'
27 + %tr
28 + %td
29 + %td
30 + = check_box_tag 'import_to_db'
31 + Import test data to database (for a test-pair task)
26 %tr
32 %tr
27 %td Time limit:
33 %td Time limit:
28 %td
34 %td
29 = text_field_tag 'time_limit'
35 = text_field_tag 'time_limit'
30 %span{:class => 'help'} In seconds. Leave blank to use 1 sec.
36 %span{:class => 'help'} In seconds. Leave blank to use 1 sec.
31 %tr
37 %tr
@@ -1,40 +1,55
1 require 'tmpdir'
1 require 'tmpdir'
2
2
3 class TestdataImporter
3 class TestdataImporter
4
4
5 attr :log_msg
5 attr :log_msg
6
6
7 - def import_from_file(problem_name,
7 + def initialize(problem)
8 - tempfile,
8 + @problem = problem
9 + end
10 +
11 + def import_from_file(tempfile,
9 time_limit,
12 time_limit,
10 - memory_limit)
13 + memory_limit,
14 + import_to_db=false)
11
15
12 - dirname = TestdataImporter.extract(problem_name, tempfile)
16 + dirname = extract(tempfile)
13 return false if not dirname
17 return false if not dirname
14 - @log_msg = GraderScript.call_import_problem(problem_name,
18 + if not import_to_db
15 - dirname,
19 + @log_msg = GraderScript.call_import_problem(@problem.name,
16 - time_limit,
20 + dirname,
17 - memory_limit)
21 + time_limit,
22 + memory_limit)
23 + else
24 + # Import test data to test pairs.
25 +
26 + @problem.test_pairs.clear
27 + if import_test_pairs(dirname)
28 + test_pair_count = TestPair.count :conditions => "problem_id = #{@problem.id}"
29 + @log_msg = "Importing test pair successful. (#{test_pair_count} test pairs imported)"
30 + else
31 + @log_msg = "Importing test pair failed. (0 test pairs imported)"
32 + end
33 + end
18 return true
34 return true
19 end
35 end
20
36
21 protected
37 protected
22
38
23 def self.long_ext(filename)
39 def self.long_ext(filename)
24 i = filename.index('.')
40 i = filename.index('.')
25 len = filename.length
41 len = filename.length
26 return filename.slice(i..len)
42 return filename.slice(i..len)
27 end
43 end
28
44
29 - def self.extract(problem_name, tempfile)
45 + def extract(tempfile)
30 - testdata_filename = TestdataImporter.save_testdata_file(problem_name,
46 + testdata_filename = save_testdata_file(tempfile)
31 - tempfile)
32 ext = TestdataImporter.long_ext(tempfile.original_filename)
47 ext = TestdataImporter.long_ext(tempfile.original_filename)
33
48
34 - extract_dir = File.join(GraderScript.raw_dir, problem_name)
49 + extract_dir = File.join(GraderScript.raw_dir, @problem.name)
35 begin
50 begin
36 Dir.mkdir extract_dir
51 Dir.mkdir extract_dir
37 rescue Errno::EEXIST
52 rescue Errno::EEXIST
38 end
53 end
39
54
40 if ext=='.tar.gz' or ext=='.tgz'
55 if ext=='.tar.gz' or ext=='.tgz'
@@ -52,15 +67,15
52 files = Dir["#{extract_dir}/**/*1*.in"]
67 files = Dir["#{extract_dir}/**/*1*.in"]
53 return nil if files.length==0
68 return nil if files.length==0
54
69
55 return File.dirname(files[0])
70 return File.dirname(files[0])
56 end
71 end
57
72
58 - def self.save_testdata_file(problem_name, tempfile)
73 + def save_testdata_file(tempfile)
59 ext = TestdataImporter.long_ext(tempfile.original_filename)
74 ext = TestdataImporter.long_ext(tempfile.original_filename)
60 - testdata_filename = File.join(Dir.tmpdir,"#{problem_name}#{ext}")
75 + testdata_filename = File.join(Dir.tmpdir,"#{@problem.name}#{ext}")
61
76
62 return nil if tempfile==""
77 return nil if tempfile==""
63
78
64 if tempfile.instance_of?(Tempfile)
79 if tempfile.instance_of?(Tempfile)
65 tempfile.close
80 tempfile.close
66 FileUtils.move(tempfile.path,testdata_filename)
81 FileUtils.move(tempfile.path,testdata_filename)
@@ -70,7 +85,25
70 end
85 end
71 end
86 end
72
87
73 return testdata_filename
88 return testdata_filename
74 end
89 end
75
90
91 + def import_test_pairs(dirname)
92 + test_num = 1
93 + while FileTest.exists? "#{dirname}/#{test_num}.in"
94 + in_filename = "#{dirname}/#{test_num}.in"
95 + sol_filename = "#{dirname}/#{test_num}.sol"
96 +
97 + break if not FileTest.exists? sol_filename
98 +
99 + test_pair = TestPair.new(:input => open(in_filename).read,
100 + :solution => open(sol_filename).read,
101 + :problem => @problem)
102 + break if not test_pair.save
103 +
104 + test_num += 1
105 + end
106 + return test_num > 1
107 + end
108 +
76 end
109 end
You need to be logged in to leave comments. Login now