Description:
imports task description as pdf
Commit status:
[Not Reviewed]
References:
Comments:
0 Commit comments 0 Inline Comments
Unresolved TODOs:
There are no unresolved TODOs
Add another comment

r271:69482b83f9d6 - - 8 files changed: 62 inserted, 9 deleted

@@ -0,0 +1,1
1 + [a-zA-Z]*
@@ -0,0 +1,9
1 + class AddDescriptionFilenameToProblems < ActiveRecord::Migration
2 + def self.up
3 + add_column :problems, :description_filename, :string
4 + end
5 +
6 + def self.down
7 + remove_column :problems, :description_filename
8 + end
9 + end
@@ -1,44 +1,54
1 class TasksController < ApplicationController
1 class TasksController < ApplicationController
2
2
3 before_filter :authenticate, :check_viewability
3 before_filter :authenticate, :check_viewability
4
4
5 def index
5 def index
6 redirect_to :action => 'list'
6 redirect_to :action => 'list'
7 end
7 end
8
8
9 def list
9 def list
10 @problems = Problem.find_available_problems
10 @problems = Problem.find_available_problems
11 @user = User.find(session[:user_id])
11 @user = User.find(session[:user_id])
12 end
12 end
13
13
14 def view
14 def view
15 - base_filename = File.basename("#{params[:file]}.#{params[:ext]}")
15 + base_name = params[:file]
16 - filename = "#{RAILS_ROOT}/data/tasks/#{base_filename}"
16 + if !check_user_viewability(base_name)
17 - #filename = "/home/ioi/web_grader/data/tasks/#{base_filename}"
17 + redirect_to :action => 'index' and return
18 - #filename = "/home/ioi/web_grader/public/images/rails.png"
18 + end
19 - if !FileTest.exists?(filename)
19 +
20 + base_filename = File.basename("#{base_name}.#{params[:ext]}")
21 + filename = "#{Problem.download_file_basedir}/#{base_filename}"
22 +
23 + if !check_user_viewability(base_name) or !FileTest.exists?(filename)
20 redirect_to :action => 'index' and return
24 redirect_to :action => 'index' and return
21 end
25 end
22
26
23 if defined?(USE_APACHE_XSENDFILE) and USE_APACHE_XSENDFILE
27 if defined?(USE_APACHE_XSENDFILE) and USE_APACHE_XSENDFILE
24 response.headers['Content-Type'] = "application/force-download"
28 response.headers['Content-Type'] = "application/force-download"
25 response.headers['Content-Disposition'] = "attachment; filename=\"#{File.basename(filename)}\""
29 response.headers['Content-Disposition'] = "attachment; filename=\"#{File.basename(filename)}\""
26 response.headers["X-Sendfile"] = filename
30 response.headers["X-Sendfile"] = filename
27 response.headers['Content-length'] = File.size(filename)
31 response.headers['Content-length'] = File.size(filename)
28 render :nothing => true
32 render :nothing => true
29 else
33 else
30 send_file filename, :stream => false, :filename => base_filename
34 send_file filename, :stream => false, :filename => base_filename
31 end
35 end
32 end
36 end
33
37
34 protected
38 protected
35
39
36 def check_viewability
40 def check_viewability
37 - user = User.find(session[:user_id])
41 + @user = User.find(session[:user_id])
38 - if user==nil or !Configuration.show_tasks_to?(user)
42 + if @user==nil or !Configuration.show_tasks_to?(@user)
39 redirect_to :controller => 'main', :action => 'list'
43 redirect_to :controller => 'main', :action => 'list'
40 return false
44 return false
41 end
45 end
42 end
46 end
43
47
48 + def check_user_viewability(filename)
49 + # individual file access control shall be added here
50 + return false if not @user
51 + return Configuration.show_tasks_to?(@user)
44 end
52 end
53 +
54 + end
@@ -1,3 +1,18
1 module MainHelper
1 module MainHelper
2
2
3 + def link_to_description_if_any(name, problem, options={})
4 + if !problem.url.blank?
5 + return link_to name, problem.url, options
6 + elsif !problem.description_filename.blank?
7 + basename, ext = problem.description_filename.split('.')
8 + options[:controller] = 'tasks'
9 + options[:action] = 'view'
10 + options[:file] = basename
11 + options[:ext] = ext
12 + return link_to name, options
13 + else
14 + return ''
3 end
15 end
16 + end
17 +
18 + end
@@ -2,96 +2,100
2
2
3 belongs_to :description
3 belongs_to :description
4 has_and_belongs_to_many :contests
4 has_and_belongs_to_many :contests
5 has_many :test_pairs, :dependent => :delete_all
5 has_many :test_pairs, :dependent => :delete_all
6
6
7 validates_presence_of :name
7 validates_presence_of :name
8 validates_format_of :name, :with => /^\w+$/
8 validates_format_of :name, :with => /^\w+$/
9 validates_presence_of :full_name
9 validates_presence_of :full_name
10
10
11 DEFAULT_TIME_LIMIT = 1
11 DEFAULT_TIME_LIMIT = 1
12 DEFAULT_MEMORY_LIMIT = 32
12 DEFAULT_MEMORY_LIMIT = 32
13
13
14 def self.find_available_problems
14 def self.find_available_problems
15 find(:all, :conditions => {:available => true}, :order => "date_added DESC")
15 find(:all, :conditions => {:available => true}, :order => "date_added DESC")
16 end
16 end
17
17
18 def self.create_from_import_form_params(params, old_problem=nil)
18 def self.create_from_import_form_params(params, old_problem=nil)
19 problem = old_problem || Problem.new
19 problem = old_problem || Problem.new
20 import_params = Problem.extract_params_and_check(params, problem)
20 import_params = Problem.extract_params_and_check(params, problem)
21
21
22 if not problem.valid?
22 if not problem.valid?
23 return problem, 'Error importing'
23 return problem, 'Error importing'
24 end
24 end
25
25
26 problem.full_score = 100
26 problem.full_score = 100
27 problem.date_added = Time.new
27 problem.date_added = Time.new
28 problem.test_allowed = true
28 problem.test_allowed = true
29 problem.output_only = false
29 problem.output_only = false
30 problem.available = false
30 problem.available = false
31
31
32 if not problem.save
32 if not problem.save
33 return problem, 'Error importing'
33 return problem, 'Error importing'
34 end
34 end
35
35
36 import_to_db = params.has_key? :import_to_db
36 import_to_db = params.has_key? :import_to_db
37
37
38 importer = TestdataImporter.new(problem)
38 importer = TestdataImporter.new(problem)
39
39
40 if not importer.import_from_file(import_params[:file],
40 if not importer.import_from_file(import_params[:file],
41 import_params[:time_limit],
41 import_params[:time_limit],
42 import_params[:memory_limit],
42 import_params[:memory_limit],
43 import_to_db)
43 import_to_db)
44 problem.errors.add_to_base('Import error.')
44 problem.errors.add_to_base('Import error.')
45 end
45 end
46
46
47 return problem, importer.log_msg
47 return problem, importer.log_msg
48 end
48 end
49
49
50 + def self.download_file_basedir
51 + return "#{RAILS_ROOT}/data/tasks"
52 + end
53 +
50 protected
54 protected
51
55
52 def self.to_i_or_default(st, default)
56 def self.to_i_or_default(st, default)
53 if st!=''
57 if st!=''
54 st.to_i
58 st.to_i
55 else
59 else
56 default
60 default
57 end
61 end
58 end
62 end
59
63
60 def self.extract_params_and_check(params, problem)
64 def self.extract_params_and_check(params, problem)
61 time_limit = Problem.to_i_or_default(params[:time_limit],
65 time_limit = Problem.to_i_or_default(params[:time_limit],
62 DEFAULT_TIME_LIMIT)
66 DEFAULT_TIME_LIMIT)
63 memory_limit = Problem.to_i_or_default(params[:memory_limit],
67 memory_limit = Problem.to_i_or_default(params[:memory_limit],
64 DEFAULT_MEMORY_LIMIT)
68 DEFAULT_MEMORY_LIMIT)
65
69
66 if time_limit==0 and time_limit_s!='0'
70 if time_limit==0 and time_limit_s!='0'
67 problem.errors.add_to_base('Time limit format errors.')
71 problem.errors.add_to_base('Time limit format errors.')
68 elsif time_limit<=0 or time_limit >60
72 elsif time_limit<=0 or time_limit >60
69 problem.errors.add_to_base('Time limit out of range.')
73 problem.errors.add_to_base('Time limit out of range.')
70 end
74 end
71
75
72 if memory_limit==0 and memory_limit_s!='0'
76 if memory_limit==0 and memory_limit_s!='0'
73 problem.errors.add_to_base('Memory limit format errors.')
77 problem.errors.add_to_base('Memory limit format errors.')
74 elsif memory_limit<=0 or memory_limit >512
78 elsif memory_limit<=0 or memory_limit >512
75 problem.errors.add_to_base('Memory limit out of range.')
79 problem.errors.add_to_base('Memory limit out of range.')
76 end
80 end
77
81
78 if params[:file]==nil or params[:file]==''
82 if params[:file]==nil or params[:file]==''
79 problem.errors.add_to_base('No testdata file.')
83 problem.errors.add_to_base('No testdata file.')
80 end
84 end
81
85
82 file = params[:file]
86 file = params[:file]
83
87
84 if problem.errors.length!=0
88 if problem.errors.length!=0
85 return problem
89 return problem
86 end
90 end
87
91
88 problem.name = params[:name]
92 problem.name = params[:name]
89 if params[:full_name]!=''
93 if params[:full_name]!=''
90 problem.full_name = params[:full_name]
94 problem.full_name = params[:full_name]
91 else
95 else
92 problem.full_name = params[:name]
96 problem.full_name = params[:name]
93 end
97 end
94
98
95 return {
99 return {
96 :time_limit => time_limit,
100 :time_limit => time_limit,
97 :memory_limit => memory_limit,
101 :memory_limit => memory_limit,
@@ -1,18 +1,18
1 <tr class="info-<%= (problem_counter%2==0) ? "even" : "odd" %>">
1 <tr class="info-<%= (problem_counter%2==0) ? "even" : "odd" %>">
2 <td>
2 <td>
3 <%= "#{problem_counter+1}" %>
3 <%= "#{problem_counter+1}" %>
4 </td>
4 </td>
5 <td>
5 <td>
6 <%= "#{problem.full_name} (#{problem.name})" %>
6 <%= "#{problem.full_name} (#{problem.name})" %>
7 - <%= link_to "[#{t 'main.problem_desc'}]", problem.url, :popup => true if (problem.url!=nil) and (problem.url!='') %>
7 + <%= link_to_description_if_any "[#{t 'main.problem_desc'}]", problem %>
8 </td>
8 </td>
9 <td align="center">
9 <td align="center">
10 <%= @prob_submissions[problem_counter][:count] %>
10 <%= @prob_submissions[problem_counter][:count] %>
11 </td>
11 </td>
12 <td>
12 <td>
13 <%= render :partial => 'submission_short',
13 <%= render :partial => 'submission_short',
14 :locals => {
14 :locals => {
15 :submission => @prob_submissions[problem_counter][:submission],
15 :submission => @prob_submissions[problem_counter][:submission],
16 :problem_name => problem.name }%>
16 :problem_name => problem.name }%>
17 </td>
17 </td>
18 </tr>
18 </tr>
@@ -1,60 +1,60
1 # This file is auto-generated from the current state of the database. Instead of editing this file,
1 # This file is auto-generated from the current state of the database. Instead of editing this file,
2 # please use the migrations feature of Active Record to incrementally modify your database, and
2 # please use the migrations feature of Active Record to incrementally modify your database, and
3 # then regenerate this schema definition.
3 # then regenerate this schema definition.
4 #
4 #
5 # Note that this schema.rb definition is the authoritative source for your database schema. If you need
5 # Note that this schema.rb definition is the authoritative source for your database schema. If you need
6 # to create the application database on another system, you should be using db:schema:load, not running
6 # to create the application database on another system, you should be using db:schema:load, not running
7 # all the migrations from scratch. The latter is a flawed and unsustainable approach (the more migrations
7 # all the migrations from scratch. The latter is a flawed and unsustainable approach (the more migrations
8 # you'll amass, the slower it'll run and the greater likelihood for issues).
8 # you'll amass, the slower it'll run and the greater likelihood for issues).
9 #
9 #
10 # It's strongly recommended to check this file into your version control system.
10 # It's strongly recommended to check this file into your version control system.
11
11
12 - ActiveRecord::Schema.define(:version => 20100216162940) do
12 + ActiveRecord::Schema.define(:version => 20100219014840) do
13
13
14 create_table "announcements", :force => true do |t|
14 create_table "announcements", :force => true do |t|
15 t.string "author"
15 t.string "author"
16 t.text "body"
16 t.text "body"
17 t.boolean "published"
17 t.boolean "published"
18 t.datetime "created_at"
18 t.datetime "created_at"
19 t.datetime "updated_at"
19 t.datetime "updated_at"
20 t.boolean "frontpage", :default => false
20 t.boolean "frontpage", :default => false
21 t.boolean "contest_only", :default => false
21 t.boolean "contest_only", :default => false
22 t.string "title"
22 t.string "title"
23 end
23 end
24
24
25 create_table "codejom_statuses", :force => true do |t|
25 create_table "codejom_statuses", :force => true do |t|
26 t.integer "user_id"
26 t.integer "user_id"
27 t.boolean "alive"
27 t.boolean "alive"
28 t.integer "num_problems_passed"
28 t.integer "num_problems_passed"
29 t.datetime "created_at"
29 t.datetime "created_at"
30 t.datetime "updated_at"
30 t.datetime "updated_at"
31 end
31 end
32
32
33 create_table "configurations", :force => true do |t|
33 create_table "configurations", :force => true do |t|
34 t.string "key"
34 t.string "key"
35 t.string "value_type"
35 t.string "value_type"
36 t.string "value"
36 t.string "value"
37 t.datetime "created_at"
37 t.datetime "created_at"
38 t.datetime "updated_at"
38 t.datetime "updated_at"
39 t.text "description"
39 t.text "description"
40 end
40 end
41
41
42 create_table "contests", :force => true do |t|
42 create_table "contests", :force => true do |t|
43 t.string "title"
43 t.string "title"
44 t.boolean "enabled"
44 t.boolean "enabled"
45 t.datetime "created_at"
45 t.datetime "created_at"
46 t.datetime "updated_at"
46 t.datetime "updated_at"
47 end
47 end
48
48
49 create_table "contests_problems", :id => false, :force => true do |t|
49 create_table "contests_problems", :id => false, :force => true do |t|
50 t.integer "contest_id"
50 t.integer "contest_id"
51 t.integer "problem_id"
51 t.integer "problem_id"
52 end
52 end
53
53
54 create_table "contests_users", :id => false, :force => true do |t|
54 create_table "contests_users", :id => false, :force => true do |t|
55 t.integer "contest_id"
55 t.integer "contest_id"
56 t.integer "user_id"
56 t.integer "user_id"
57 end
57 end
58
58
59 create_table "countries", :force => true do |t|
59 create_table "countries", :force => true do |t|
60 t.string "name"
60 t.string "name"
@@ -67,96 +67,97
67 t.boolean "markdowned"
67 t.boolean "markdowned"
68 t.datetime "created_at"
68 t.datetime "created_at"
69 t.datetime "updated_at"
69 t.datetime "updated_at"
70 end
70 end
71
71
72 create_table "grader_processes", :force => true do |t|
72 create_table "grader_processes", :force => true do |t|
73 t.string "host", :limit => 20
73 t.string "host", :limit => 20
74 t.integer "pid"
74 t.integer "pid"
75 t.string "mode"
75 t.string "mode"
76 t.boolean "active"
76 t.boolean "active"
77 t.datetime "created_at"
77 t.datetime "created_at"
78 t.datetime "updated_at"
78 t.datetime "updated_at"
79 t.integer "task_id"
79 t.integer "task_id"
80 t.string "task_type"
80 t.string "task_type"
81 t.boolean "terminated"
81 t.boolean "terminated"
82 end
82 end
83
83
84 add_index "grader_processes", ["host", "pid"], :name => "index_grader_processes_on_ip_and_pid"
84 add_index "grader_processes", ["host", "pid"], :name => "index_grader_processes_on_ip_and_pid"
85
85
86 create_table "languages", :force => true do |t|
86 create_table "languages", :force => true do |t|
87 t.string "name", :limit => 10
87 t.string "name", :limit => 10
88 t.string "pretty_name"
88 t.string "pretty_name"
89 t.string "ext", :limit => 10
89 t.string "ext", :limit => 10
90 t.string "common_ext"
90 t.string "common_ext"
91 end
91 end
92
92
93 create_table "messages", :force => true do |t|
93 create_table "messages", :force => true do |t|
94 t.integer "sender_id"
94 t.integer "sender_id"
95 t.integer "receiver_id"
95 t.integer "receiver_id"
96 t.integer "replying_message_id"
96 t.integer "replying_message_id"
97 t.text "body"
97 t.text "body"
98 t.boolean "replied"
98 t.boolean "replied"
99 t.datetime "created_at"
99 t.datetime "created_at"
100 t.datetime "updated_at"
100 t.datetime "updated_at"
101 end
101 end
102
102
103 create_table "problems", :force => true do |t|
103 create_table "problems", :force => true do |t|
104 t.string "name", :limit => 30
104 t.string "name", :limit => 30
105 t.string "full_name"
105 t.string "full_name"
106 t.integer "full_score"
106 t.integer "full_score"
107 t.date "date_added"
107 t.date "date_added"
108 t.boolean "available"
108 t.boolean "available"
109 t.string "url"
109 t.string "url"
110 t.integer "description_id"
110 t.integer "description_id"
111 t.boolean "test_allowed"
111 t.boolean "test_allowed"
112 t.boolean "output_only"
112 t.boolean "output_only"
113 t.integer "level", :default => 0
113 t.integer "level", :default => 0
114 t.datetime "updated_at"
114 t.datetime "updated_at"
115 + t.string "description_filename"
115 end
116 end
116
117
117 create_table "rights", :force => true do |t|
118 create_table "rights", :force => true do |t|
118 t.string "name"
119 t.string "name"
119 t.string "controller"
120 t.string "controller"
120 t.string "action"
121 t.string "action"
121 end
122 end
122
123
123 create_table "rights_roles", :id => false, :force => true do |t|
124 create_table "rights_roles", :id => false, :force => true do |t|
124 t.integer "right_id"
125 t.integer "right_id"
125 t.integer "role_id"
126 t.integer "role_id"
126 end
127 end
127
128
128 add_index "rights_roles", ["role_id"], :name => "index_rights_roles_on_role_id"
129 add_index "rights_roles", ["role_id"], :name => "index_rights_roles_on_role_id"
129
130
130 create_table "roles", :force => true do |t|
131 create_table "roles", :force => true do |t|
131 t.string "name"
132 t.string "name"
132 end
133 end
133
134
134 create_table "roles_users", :id => false, :force => true do |t|
135 create_table "roles_users", :id => false, :force => true do |t|
135 t.integer "role_id"
136 t.integer "role_id"
136 t.integer "user_id"
137 t.integer "user_id"
137 end
138 end
138
139
139 add_index "roles_users", ["user_id"], :name => "index_roles_users_on_user_id"
140 add_index "roles_users", ["user_id"], :name => "index_roles_users_on_user_id"
140
141
141 create_table "sessions", :force => true do |t|
142 create_table "sessions", :force => true do |t|
142 t.string "session_id"
143 t.string "session_id"
143 t.text "data"
144 t.text "data"
144 t.datetime "updated_at"
145 t.datetime "updated_at"
145 end
146 end
146
147
147 add_index "sessions", ["session_id"], :name => "index_sessions_on_session_id"
148 add_index "sessions", ["session_id"], :name => "index_sessions_on_session_id"
148 add_index "sessions", ["updated_at"], :name => "index_sessions_on_updated_at"
149 add_index "sessions", ["updated_at"], :name => "index_sessions_on_updated_at"
149
150
150 create_table "sites", :force => true do |t|
151 create_table "sites", :force => true do |t|
151 t.string "name"
152 t.string "name"
152 t.boolean "started"
153 t.boolean "started"
153 t.datetime "start_time"
154 t.datetime "start_time"
154 t.datetime "created_at"
155 t.datetime "created_at"
155 t.datetime "updated_at"
156 t.datetime "updated_at"
156 t.integer "country_id"
157 t.integer "country_id"
157 t.string "password"
158 t.string "password"
158 end
159 end
159
160
160 create_table "submission_statuses", :force => true do |t|
161 create_table "submission_statuses", :force => true do |t|
161 t.integer "user_id"
162 t.integer "user_id"
162 t.integer "problem_id"
163 t.integer "problem_id"
@@ -1,83 +1,84
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 initialize(problem)
7 def initialize(problem)
8 @problem = problem
8 @problem = problem
9 end
9 end
10
10
11 def import_from_file(tempfile,
11 def import_from_file(tempfile,
12 time_limit,
12 time_limit,
13 memory_limit,
13 memory_limit,
14 import_to_db=false)
14 import_to_db=false)
15
15
16 dirname = extract(tempfile)
16 dirname = extract(tempfile)
17 return false if not dirname
17 return false if not dirname
18 if not import_to_db
18 if not import_to_db
19 @log_msg = GraderScript.call_import_problem(@problem.name,
19 @log_msg = GraderScript.call_import_problem(@problem.name,
20 dirname,
20 dirname,
21 time_limit,
21 time_limit,
22 memory_limit)
22 memory_limit)
23 else
23 else
24 # Import test data to test pairs.
24 # Import test data to test pairs.
25
25
26 @problem.test_pairs.clear
26 @problem.test_pairs.clear
27 if import_test_pairs(dirname)
27 if import_test_pairs(dirname)
28 test_pair_count = TestPair.count :conditions => "problem_id = #{@problem.id}"
28 test_pair_count = TestPair.count :conditions => "problem_id = #{@problem.id}"
29 @log_msg = "Importing test pair successful. (#{test_pair_count} test pairs imported)"
29 @log_msg = "Importing test pair successful. (#{test_pair_count} test pairs imported)"
30 else
30 else
31 @log_msg = "Importing test pair failed. (0 test pairs imported)"
31 @log_msg = "Importing test pair failed. (0 test pairs imported)"
32 end
32 end
33 end
33 end
34
34
35 @log_msg << import_problem_description(dirname)
35 @log_msg << import_problem_description(dirname)
36 + @log_msg << import_problem_pdf(dirname)
36
37
37 return true
38 return true
38 end
39 end
39
40
40 protected
41 protected
41
42
42 def self.long_ext(filename)
43 def self.long_ext(filename)
43 i = filename.index('.')
44 i = filename.index('.')
44 len = filename.length
45 len = filename.length
45 return filename.slice(i..len)
46 return filename.slice(i..len)
46 end
47 end
47
48
48 def extract(tempfile)
49 def extract(tempfile)
49 testdata_filename = save_testdata_file(tempfile)
50 testdata_filename = save_testdata_file(tempfile)
50 ext = TestdataImporter.long_ext(tempfile.original_filename)
51 ext = TestdataImporter.long_ext(tempfile.original_filename)
51
52
52 extract_dir = File.join(GraderScript.raw_dir, @problem.name)
53 extract_dir = File.join(GraderScript.raw_dir, @problem.name)
53 begin
54 begin
54 Dir.mkdir extract_dir
55 Dir.mkdir extract_dir
55 rescue Errno::EEXIST
56 rescue Errno::EEXIST
56 end
57 end
57
58
58 if ext=='.tar.gz' or ext=='.tgz'
59 if ext=='.tar.gz' or ext=='.tgz'
59 cmd = "tar -zxvf #{testdata_filename} -C #{extract_dir}"
60 cmd = "tar -zxvf #{testdata_filename} -C #{extract_dir}"
60 elsif ext=='.tar'
61 elsif ext=='.tar'
61 cmd = "tar -xvf #{testdata_filename} -C #{extract_dir}"
62 cmd = "tar -xvf #{testdata_filename} -C #{extract_dir}"
62 elsif ext=='.zip'
63 elsif ext=='.zip'
63 cmd = "unzip -o #{testdata_filename} -d #{extract_dir}"
64 cmd = "unzip -o #{testdata_filename} -d #{extract_dir}"
64 else
65 else
65 return nil
66 return nil
66 end
67 end
67
68
68 system(cmd)
69 system(cmd)
69
70
70 files = Dir["#{extract_dir}/**/*1*.in"]
71 files = Dir["#{extract_dir}/**/*1*.in"]
71 return nil if files.length==0
72 return nil if files.length==0
72
73
73 File.delete(testdata_filename)
74 File.delete(testdata_filename)
74
75
75 return File.dirname(files[0])
76 return File.dirname(files[0])
76 end
77 end
77
78
78 def save_testdata_file(tempfile)
79 def save_testdata_file(tempfile)
79 ext = TestdataImporter.long_ext(tempfile.original_filename)
80 ext = TestdataImporter.long_ext(tempfile.original_filename)
80 testdata_filename = File.join(Dir.tmpdir,"#{@problem.name}#{ext}")
81 testdata_filename = File.join(Dir.tmpdir,"#{@problem.name}#{ext}")
81
82
82 return nil if tempfile==""
83 return nil if tempfile==""
83
84
@@ -90,49 +91,61
90 end
91 end
91 end
92 end
92
93
93 return testdata_filename
94 return testdata_filename
94 end
95 end
95
96
96 def import_test_pairs(dirname)
97 def import_test_pairs(dirname)
97 test_num = 1
98 test_num = 1
98 while FileTest.exists? "#{dirname}/#{test_num}.in"
99 while FileTest.exists? "#{dirname}/#{test_num}.in"
99 in_filename = "#{dirname}/#{test_num}.in"
100 in_filename = "#{dirname}/#{test_num}.in"
100 sol_filename = "#{dirname}/#{test_num}.sol"
101 sol_filename = "#{dirname}/#{test_num}.sol"
101
102
102 break if not FileTest.exists? sol_filename
103 break if not FileTest.exists? sol_filename
103
104
104 test_pair = TestPair.new(:input => open(in_filename).read,
105 test_pair = TestPair.new(:input => open(in_filename).read,
105 :solution => open(sol_filename).read,
106 :solution => open(sol_filename).read,
106 :problem => @problem)
107 :problem => @problem)
107 break if not test_pair.save
108 break if not test_pair.save
108
109
109 test_num += 1
110 test_num += 1
110 end
111 end
111 return test_num > 1
112 return test_num > 1
112 end
113 end
113
114
114 def import_problem_description(dirname)
115 def import_problem_description(dirname)
115 html_files = Dir["#{dirname}/*.html"]
116 html_files = Dir["#{dirname}/*.html"]
116 markdown_files = Dir["#{dirname}/*.md"] + Dir["#{dirname}/*.markdown"]
117 markdown_files = Dir["#{dirname}/*.md"] + Dir["#{dirname}/*.markdown"]
117 if (html_files.length != 0) or (markdown_files.length != 0)
118 if (html_files.length != 0) or (markdown_files.length != 0)
118 description = @problem.description || Description.new
119 description = @problem.description || Description.new
119
120
120 if html_files.length != 0
121 if html_files.length != 0
121 filename = html_files[0]
122 filename = html_files[0]
122 description.markdowned = false
123 description.markdowned = false
123 else
124 else
124 filename = markdown_files[0]
125 filename = markdown_files[0]
125 description.markdowned = true
126 description.markdowned = true
126 end
127 end
127
128
128 description.body = open(filename).read
129 description.body = open(filename).read
129 description.save
130 description.save
130 @problem.description = description
131 @problem.description = description
131 @problem.save
132 @problem.save
132 return "\nProblem description imported from #{filename}."
133 return "\nProblem description imported from #{filename}."
133 else
134 else
134 return ''
135 return ''
135 end
136 end
136 end
137 end
137
138
139 + def import_problem_pdf(dirname)
140 + pdf_files = Dir["#{dirname}/*.pdf"]
141 + if pdf_files.length != 0
142 + filename = pdf_files[0]
143 + out_filename = "#{Problem.download_file_basedir}/#{@problem.name}.pdf"
144 + File.rename(filename, out_filename)
145 + @problem.description_filename = "#{@problem.name}.pdf"
146 + @problem.save
147 + return "\nProblem pdf imported from #{filename}."
138 end
148 end
149 + end
150 +
151 + end
You need to be logged in to leave comments. Login now