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 1 class TasksController < ApplicationController
2 2
3 3 before_filter :authenticate, :check_viewability
4 4
5 5 def index
6 6 redirect_to :action => 'list'
7 7 end
8 8
9 9 def list
10 10 @problems = Problem.find_available_problems
11 11 @user = User.find(session[:user_id])
12 12 end
13 13
14 14 def view
15 - base_filename = File.basename("#{params[:file]}.#{params[:ext]}")
16 - filename = "#{RAILS_ROOT}/data/tasks/#{base_filename}"
17 - #filename = "/home/ioi/web_grader/data/tasks/#{base_filename}"
18 - #filename = "/home/ioi/web_grader/public/images/rails.png"
19 - if !FileTest.exists?(filename)
15 + base_name = params[:file]
16 + if !check_user_viewability(base_name)
17 + redirect_to :action => 'index' and return
18 + end
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 24 redirect_to :action => 'index' and return
21 25 end
22 26
23 27 if defined?(USE_APACHE_XSENDFILE) and USE_APACHE_XSENDFILE
24 28 response.headers['Content-Type'] = "application/force-download"
25 29 response.headers['Content-Disposition'] = "attachment; filename=\"#{File.basename(filename)}\""
26 30 response.headers["X-Sendfile"] = filename
27 31 response.headers['Content-length'] = File.size(filename)
28 32 render :nothing => true
29 33 else
30 34 send_file filename, :stream => false, :filename => base_filename
31 35 end
32 36 end
33 37
34 38 protected
35 39
36 40 def check_viewability
37 - user = User.find(session[:user_id])
38 - if user==nil or !Configuration.show_tasks_to?(user)
41 + @user = User.find(session[:user_id])
42 + if @user==nil or !Configuration.show_tasks_to?(@user)
39 43 redirect_to :controller => 'main', :action => 'list'
40 44 return false
41 45 end
42 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 52 end
53 +
54 + end
@@ -1,3 +1,18
1 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 15 end
16 + end
17 +
18 + end
@@ -26,48 +26,52
26 26 problem.full_score = 100
27 27 problem.date_added = Time.new
28 28 problem.test_allowed = true
29 29 problem.output_only = false
30 30 problem.available = false
31 31
32 32 if not problem.save
33 33 return problem, 'Error importing'
34 34 end
35 35
36 36 import_to_db = params.has_key? :import_to_db
37 37
38 38 importer = TestdataImporter.new(problem)
39 39
40 40 if not importer.import_from_file(import_params[:file],
41 41 import_params[:time_limit],
42 42 import_params[:memory_limit],
43 43 import_to_db)
44 44 problem.errors.add_to_base('Import error.')
45 45 end
46 46
47 47 return problem, importer.log_msg
48 48 end
49 49
50 + def self.download_file_basedir
51 + return "#{RAILS_ROOT}/data/tasks"
52 + end
53 +
50 54 protected
51 55
52 56 def self.to_i_or_default(st, default)
53 57 if st!=''
54 58 st.to_i
55 59 else
56 60 default
57 61 end
58 62 end
59 63
60 64 def self.extract_params_and_check(params, problem)
61 65 time_limit = Problem.to_i_or_default(params[:time_limit],
62 66 DEFAULT_TIME_LIMIT)
63 67 memory_limit = Problem.to_i_or_default(params[:memory_limit],
64 68 DEFAULT_MEMORY_LIMIT)
65 69
66 70 if time_limit==0 and time_limit_s!='0'
67 71 problem.errors.add_to_base('Time limit format errors.')
68 72 elsif time_limit<=0 or time_limit >60
69 73 problem.errors.add_to_base('Time limit out of range.')
70 74 end
71 75
72 76 if memory_limit==0 and memory_limit_s!='0'
73 77 problem.errors.add_to_base('Memory limit format errors.')
@@ -1,18 +1,18
1 1 <tr class="info-<%= (problem_counter%2==0) ? "even" : "odd" %>">
2 2 <td>
3 3 <%= "#{problem_counter+1}" %>
4 4 </td>
5 5 <td>
6 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 8 </td>
9 9 <td align="center">
10 10 <%= @prob_submissions[problem_counter][:count] %>
11 11 </td>
12 12 <td>
13 13 <%= render :partial => 'submission_short',
14 14 :locals => {
15 15 :submission => @prob_submissions[problem_counter][:submission],
16 16 :problem_name => problem.name }%>
17 17 </td>
18 18 </tr>
@@ -1,36 +1,36
1 1 # This file is auto-generated from the current state of the database. Instead of editing this file,
2 2 # please use the migrations feature of Active Record to incrementally modify your database, and
3 3 # then regenerate this schema definition.
4 4 #
5 5 # Note that this schema.rb definition is the authoritative source for your database schema. If you need
6 6 # to create the application database on another system, you should be using db:schema:load, not running
7 7 # all the migrations from scratch. The latter is a flawed and unsustainable approach (the more migrations
8 8 # you'll amass, the slower it'll run and the greater likelihood for issues).
9 9 #
10 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 14 create_table "announcements", :force => true do |t|
15 15 t.string "author"
16 16 t.text "body"
17 17 t.boolean "published"
18 18 t.datetime "created_at"
19 19 t.datetime "updated_at"
20 20 t.boolean "frontpage", :default => false
21 21 t.boolean "contest_only", :default => false
22 22 t.string "title"
23 23 end
24 24
25 25 create_table "codejom_statuses", :force => true do |t|
26 26 t.integer "user_id"
27 27 t.boolean "alive"
28 28 t.integer "num_problems_passed"
29 29 t.datetime "created_at"
30 30 t.datetime "updated_at"
31 31 end
32 32
33 33 create_table "configurations", :force => true do |t|
34 34 t.string "key"
35 35 t.string "value_type"
36 36 t.string "value"
@@ -91,48 +91,49
91 91 end
92 92
93 93 create_table "messages", :force => true do |t|
94 94 t.integer "sender_id"
95 95 t.integer "receiver_id"
96 96 t.integer "replying_message_id"
97 97 t.text "body"
98 98 t.boolean "replied"
99 99 t.datetime "created_at"
100 100 t.datetime "updated_at"
101 101 end
102 102
103 103 create_table "problems", :force => true do |t|
104 104 t.string "name", :limit => 30
105 105 t.string "full_name"
106 106 t.integer "full_score"
107 107 t.date "date_added"
108 108 t.boolean "available"
109 109 t.string "url"
110 110 t.integer "description_id"
111 111 t.boolean "test_allowed"
112 112 t.boolean "output_only"
113 113 t.integer "level", :default => 0
114 114 t.datetime "updated_at"
115 + t.string "description_filename"
115 116 end
116 117
117 118 create_table "rights", :force => true do |t|
118 119 t.string "name"
119 120 t.string "controller"
120 121 t.string "action"
121 122 end
122 123
123 124 create_table "rights_roles", :id => false, :force => true do |t|
124 125 t.integer "right_id"
125 126 t.integer "role_id"
126 127 end
127 128
128 129 add_index "rights_roles", ["role_id"], :name => "index_rights_roles_on_role_id"
129 130
130 131 create_table "roles", :force => true do |t|
131 132 t.string "name"
132 133 end
133 134
134 135 create_table "roles_users", :id => false, :force => true do |t|
135 136 t.integer "role_id"
136 137 t.integer "user_id"
137 138 end
138 139
@@ -12,48 +12,49
12 12 time_limit,
13 13 memory_limit,
14 14 import_to_db=false)
15 15
16 16 dirname = extract(tempfile)
17 17 return false if not dirname
18 18 if not import_to_db
19 19 @log_msg = GraderScript.call_import_problem(@problem.name,
20 20 dirname,
21 21 time_limit,
22 22 memory_limit)
23 23 else
24 24 # Import test data to test pairs.
25 25
26 26 @problem.test_pairs.clear
27 27 if import_test_pairs(dirname)
28 28 test_pair_count = TestPair.count :conditions => "problem_id = #{@problem.id}"
29 29 @log_msg = "Importing test pair successful. (#{test_pair_count} test pairs imported)"
30 30 else
31 31 @log_msg = "Importing test pair failed. (0 test pairs imported)"
32 32 end
33 33 end
34 34
35 35 @log_msg << import_problem_description(dirname)
36 + @log_msg << import_problem_pdf(dirname)
36 37
37 38 return true
38 39 end
39 40
40 41 protected
41 42
42 43 def self.long_ext(filename)
43 44 i = filename.index('.')
44 45 len = filename.length
45 46 return filename.slice(i..len)
46 47 end
47 48
48 49 def extract(tempfile)
49 50 testdata_filename = save_testdata_file(tempfile)
50 51 ext = TestdataImporter.long_ext(tempfile.original_filename)
51 52
52 53 extract_dir = File.join(GraderScript.raw_dir, @problem.name)
53 54 begin
54 55 Dir.mkdir extract_dir
55 56 rescue Errno::EEXIST
56 57 end
57 58
58 59 if ext=='.tar.gz' or ext=='.tgz'
59 60 cmd = "tar -zxvf #{testdata_filename} -C #{extract_dir}"
@@ -114,25 +115,37
114 115 def import_problem_description(dirname)
115 116 html_files = Dir["#{dirname}/*.html"]
116 117 markdown_files = Dir["#{dirname}/*.md"] + Dir["#{dirname}/*.markdown"]
117 118 if (html_files.length != 0) or (markdown_files.length != 0)
118 119 description = @problem.description || Description.new
119 120
120 121 if html_files.length != 0
121 122 filename = html_files[0]
122 123 description.markdowned = false
123 124 else
124 125 filename = markdown_files[0]
125 126 description.markdowned = true
126 127 end
127 128
128 129 description.body = open(filename).read
129 130 description.save
130 131 @problem.description = description
131 132 @problem.save
132 133 return "\nProblem description imported from #{filename}."
133 134 else
134 135 return ''
135 136 end
136 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 148 end
149 + end
150 +
151 + end
You need to be logged in to leave comments. Login now