Description:
- add view testcase toggle for each problem - refactor: move view testcase to testcase_controller - change flash rendering
Commit status:
[Not Reviewed]
References:
Comments:
0 Commit comments 0 Inline Comments
Unresolved TODOs:
There are no unresolved TODOs
Add another comment

r632:b4dd5e5f23ab - - 14 files changed: 130 inserted, 71 deleted

@@ -0,0 +1,2
1 + = render partial: 'toggle_button',
2 + locals: {button_id: "#problem-view-testcase-#{@problem.id}",button_on: @problem.view_testcase?}
@@ -0,0 +1,25
1 + %h1 Test cases
2 + %h2= @problem.long_name
3 +
4 + /navbar
5 + %ul.nav.nav-pills{role: :tablist}
6 + - @problem.testcases.each.with_index do |tc,id|
7 + %li{role: :presentation, class: ('active' if id == 0)}
8 + %a{href:"#tc#{tc.id}", role: 'tab', data: {toggle: 'tab'}}= tc.num
9 +
10 + /actual data
11 + .tab-content
12 + - @problem.testcases.each.with_index do |tc,id|
13 + .tab-pane{id: "tc#{tc.id}",class: ('active' if id == 0)}
14 + .row
15 + .col-md-6
16 + %h3 Input
17 + = link_to "Download",download_input_testcase_path(tc),class: 'btn btn-info btn-sm'
18 + .col-md-6
19 + %h3 Output
20 + = link_to "Download",download_sol_testcase_path(tc),class: 'btn btn-info btn-sm'
21 + .row
22 + .col-md-6
23 + %textarea{ rows: 25,readonly: true,style: "width:100%;resize=none;overflow-y: scroll;"}= tc.input
24 + .col-md-6
25 + %textarea{ rows: 25,readonly: true,style: "width:100%;resize=none;overflow-y: scroll;"}= tc.sol
@@ -0,0 +1,5
1 + class AddViewTestcaseToProblem < ActiveRecord::Migration
2 + def change
3 + add_column :problems, :view_testcase, :bool
4 + end
5 + end
@@ -18,53 +18,56
18 @current_user ||= User.find(session[:user_id])
18 @current_user ||= User.find(session[:user_id])
19 end
19 end
20
20
21 def admin_authorization
21 def admin_authorization
22 return false unless authenticate
22 return false unless authenticate
23 user = User.includes(:roles).find(session[:user_id])
23 user = User.includes(:roles).find(session[:user_id])
24 unless user.admin?
24 unless user.admin?
25 unauthorized_redirect
25 unauthorized_redirect
26 return false
26 return false
27 end
27 end
28 return true
28 return true
29 end
29 end
30
30
31 def authorization_by_roles(allowed_roles)
31 def authorization_by_roles(allowed_roles)
32 return false unless authenticate
32 return false unless authenticate
33 user = User.find(session[:user_id])
33 user = User.find(session[:user_id])
34 unless user.roles.detect { |role| allowed_roles.member?(role.name) }
34 unless user.roles.detect { |role| allowed_roles.member?(role.name) }
35 unauthorized_redirect
35 unauthorized_redirect
36 return false
36 return false
37 end
37 end
38 end
38 end
39
39
40 def testcase_authorization
40 def testcase_authorization
41 #admin always has privileged
41 #admin always has privileged
42 + puts "haha"
42 if @current_user.admin?
43 if @current_user.admin?
43 return true
44 return true
44 end
45 end
45
46
46 - unauthorized_redirect if GraderConfiguration["right.view_testcase"]
47 + puts "hehe"
48 + puts GraderConfiguration["right.view_testcase"]
49 + unauthorized_redirect unless GraderConfiguration["right.view_testcase"]
47 end
50 end
48
51
49 protected
52 protected
50
53
51 def authenticate
54 def authenticate
52 unless session[:user_id]
55 unless session[:user_id]
53 flash[:notice] = 'You need to login'
56 flash[:notice] = 'You need to login'
54 if GraderConfiguration[SINGLE_USER_MODE_CONF_KEY]
57 if GraderConfiguration[SINGLE_USER_MODE_CONF_KEY]
55 flash[:notice] = 'You need to login but you cannot log in at this time'
58 flash[:notice] = 'You need to login but you cannot log in at this time'
56 end
59 end
57 redirect_to :controller => 'main', :action => 'login'
60 redirect_to :controller => 'main', :action => 'login'
58 return false
61 return false
59 end
62 end
60
63
61 # check if run in single user mode
64 # check if run in single user mode
62 if GraderConfiguration[SINGLE_USER_MODE_CONF_KEY]
65 if GraderConfiguration[SINGLE_USER_MODE_CONF_KEY]
63 user = User.find_by_id(session[:user_id])
66 user = User.find_by_id(session[:user_id])
64 if user==nil or (not user.admin?)
67 if user==nil or (not user.admin?)
65 flash[:notice] = 'You cannot log in at this time'
68 flash[:notice] = 'You cannot log in at this time'
66 redirect_to :controller => 'main', :action => 'login'
69 redirect_to :controller => 'main', :action => 'login'
67 return false
70 return false
68 end
71 end
69 unless user.enabled?
72 unless user.enabled?
70 flash[:notice] = 'Your account is disabled'
73 flash[:notice] = 'Your account is disabled'
@@ -87,51 +90,53
87 end
90 end
88 return true
91 return true
89 end
92 end
90
93
91 def authenticate_by_ip_address
94 def authenticate_by_ip_address
92 #this assume that we have already authenticate normally
95 #this assume that we have already authenticate normally
93 unless GraderConfiguration[MULTIPLE_IP_LOGIN_CONF_KEY]
96 unless GraderConfiguration[MULTIPLE_IP_LOGIN_CONF_KEY]
94 user = User.find(session[:user_id])
97 user = User.find(session[:user_id])
95 if (not user.admin? and user.last_ip and user.last_ip != request.remote_ip)
98 if (not user.admin? and user.last_ip and user.last_ip != request.remote_ip)
96 flash[:notice] = "You cannot use the system from #{request.remote_ip}. Your last ip is #{user.last_ip}"
99 flash[:notice] = "You cannot use the system from #{request.remote_ip}. Your last ip is #{user.last_ip}"
97 redirect_to :controller => 'main', :action => 'login'
100 redirect_to :controller => 'main', :action => 'login'
98 puts "CHEAT: user #{user.login} tried to login from '#{request.remote_ip}' while last ip is '#{user.last_ip}' at #{Time.zone.now}"
101 puts "CHEAT: user #{user.login} tried to login from '#{request.remote_ip}' while last ip is '#{user.last_ip}' at #{Time.zone.now}"
99 return false
102 return false
100 end
103 end
101 unless user.last_ip
104 unless user.last_ip
102 user.last_ip = request.remote_ip
105 user.last_ip = request.remote_ip
103 user.save
106 user.save
104 end
107 end
105 end
108 end
106 return true
109 return true
107 end
110 end
108
111
109 def authorization
112 def authorization
110 return false unless authenticate
113 return false unless authenticate
114 + puts "haha 1"
111 user = User.find(session[:user_id])
115 user = User.find(session[:user_id])
112 unless user.roles.detect { |role|
116 unless user.roles.detect { |role|
113 - role.rights.detect{ |right|
117 + role.rights.detect{ |right|
114 - right.controller == self.class.controller_name and
118 + right.controller == self.class.controller_name and
115 - (right.action == 'all' or right.action == action_name)
119 + (right.action == 'all' or right.action == action_name)
116 - }
120 + }
117 }
121 }
122 + puts "haha 2"
118 flash[:notice] = 'You are not authorized to view the page you requested'
123 flash[:notice] = 'You are not authorized to view the page you requested'
119 #request.env['HTTP_REFERER'] ? (redirect_to :back) : (redirect_to :controller => 'login')
124 #request.env['HTTP_REFERER'] ? (redirect_to :back) : (redirect_to :controller => 'login')
120 redirect_to :controller => 'main', :action => 'login'
125 redirect_to :controller => 'main', :action => 'login'
121 return false
126 return false
122 end
127 end
123 end
128 end
124
129
125 def verify_time_limit
130 def verify_time_limit
126 return true if session[:user_id]==nil
131 return true if session[:user_id]==nil
127 user = User.find(session[:user_id], :include => :site)
132 user = User.find(session[:user_id], :include => :site)
128 return true if user==nil or user.site == nil
133 return true if user==nil or user.site == nil
129 if user.contest_finished?
134 if user.contest_finished?
130 flash[:notice] = 'Error: the contest you are participating is over.'
135 flash[:notice] = 'Error: the contest you are participating is over.'
131 redirect_to :back
136 redirect_to :back
132 return false
137 return false
133 end
138 end
134 return true
139 return true
135 end
140 end
136
141
137 end
142 end
@@ -114,48 +114,56
114 end
114 end
115 end
115 end
116
116
117 def destroy
117 def destroy
118 p = Problem.find(params[:id]).destroy
118 p = Problem.find(params[:id]).destroy
119 redirect_to action: :index
119 redirect_to action: :index
120 end
120 end
121
121
122 def toggle
122 def toggle
123 @problem = Problem.find(params[:id])
123 @problem = Problem.find(params[:id])
124 @problem.update_attributes(available: !(@problem.available) )
124 @problem.update_attributes(available: !(@problem.available) )
125 respond_to do |format|
125 respond_to do |format|
126 format.js { }
126 format.js { }
127 end
127 end
128 end
128 end
129
129
130 def toggle_test
130 def toggle_test
131 @problem = Problem.find(params[:id])
131 @problem = Problem.find(params[:id])
132 @problem.update_attributes(test_allowed: !(@problem.test_allowed?) )
132 @problem.update_attributes(test_allowed: !(@problem.test_allowed?) )
133 respond_to do |format|
133 respond_to do |format|
134 format.js { }
134 format.js { }
135 end
135 end
136 end
136 end
137
137
138 + def toggle_view_testcase
139 + @problem = Problem.find(params[:id])
140 + @problem.update_attributes(view_testcase: !(@problem.view_testcase?) )
141 + respond_to do |format|
142 + format.js { }
143 + end
144 + end
145 +
138 def turn_all_off
146 def turn_all_off
139 Problem.available.all.each do |problem|
147 Problem.available.all.each do |problem|
140 problem.available = false
148 problem.available = false
141 problem.save
149 problem.save
142 end
150 end
143 redirect_to action: :index
151 redirect_to action: :index
144 end
152 end
145
153
146 def turn_all_on
154 def turn_all_on
147 Problem.where.not(available: true).each do |problem|
155 Problem.where.not(available: true).each do |problem|
148 problem.available = true
156 problem.available = true
149 problem.save
157 problem.save
150 end
158 end
151 redirect_to action: :index
159 redirect_to action: :index
152 end
160 end
153
161
154 def stat
162 def stat
155 @problem = Problem.find(params[:id])
163 @problem = Problem.find(params[:id])
156 unless @problem.available or session[:admin]
164 unless @problem.available or session[:admin]
157 redirect_to :controller => 'main', :action => 'list'
165 redirect_to :controller => 'main', :action => 'list'
158 return
166 return
159 end
167 end
160 @submissions = Submission.includes(:user).where(problem_id: params[:id]).order(:user_id,:id)
168 @submissions = Submission.includes(:user).where(problem_id: params[:id]).order(:user_id,:id)
161
169
@@ -201,52 +209,48
201 params.delete :import_to_db
209 params.delete :import_to_db
202 end
210 end
203 @problem, import_log = Problem.create_from_import_form_params(params,
211 @problem, import_log = Problem.create_from_import_form_params(params,
204 old_problem)
212 old_problem)
205
213
206 if !@problem.errors.empty?
214 if !@problem.errors.empty?
207 render :action => 'import' and return
215 render :action => 'import' and return
208 end
216 end
209
217
210 if old_problem!=nil
218 if old_problem!=nil
211 flash[:notice] = "The test data has been replaced for problem #{@problem.name}"
219 flash[:notice] = "The test data has been replaced for problem #{@problem.name}"
212 end
220 end
213 @log = import_log
221 @log = import_log
214 end
222 end
215
223
216 def remove_contest
224 def remove_contest
217 problem = Problem.find(params[:id])
225 problem = Problem.find(params[:id])
218 contest = Contest.find(params[:contest_id])
226 contest = Contest.find(params[:contest_id])
219 if problem!=nil and contest!=nil
227 if problem!=nil and contest!=nil
220 problem.contests.delete(contest)
228 problem.contests.delete(contest)
221 end
229 end
222 redirect_to :action => 'manage'
230 redirect_to :action => 'manage'
223 end
231 end
224
232
225 - def show_testcase
226 - @problem = Problem.includes(:testcases).find(params[:id])
227 - end
228 -
229 ##################################
233 ##################################
230 protected
234 protected
231
235
232 def allow_test_pair_import?
236 def allow_test_pair_import?
233 if defined? ALLOW_TEST_PAIR_IMPORT
237 if defined? ALLOW_TEST_PAIR_IMPORT
234 return ALLOW_TEST_PAIR_IMPORT
238 return ALLOW_TEST_PAIR_IMPORT
235 else
239 else
236 return false
240 return false
237 end
241 end
238 end
242 end
239
243
240 def change_date_added
244 def change_date_added
241 problems = get_problems_from_params
245 problems = get_problems_from_params
242 year = params[:date_added][:year].to_i
246 year = params[:date_added][:year].to_i
243 month = params[:date_added][:month].to_i
247 month = params[:date_added][:month].to_i
244 day = params[:date_added][:day].to_i
248 day = params[:date_added][:day].to_i
245 date = Date.new(year,month,day)
249 date = Date.new(year,month,day)
246 problems.each do |p|
250 problems.each do |p|
247 p.date_added = date
251 p.date_added = date
248 p.save
252 p.save
249 end
253 end
250 end
254 end
251
255
252 def add_to_contest
256 def add_to_contest
@@ -1,24 +1,32
1 class TestcasesController < ApplicationController
1 class TestcasesController < ApplicationController
2 before_action :set_testcase, only: [:download_input,:download_sol]
2 before_action :set_testcase, only: [:download_input,:download_sol]
3 before_action :testcase_authorization
3 before_action :testcase_authorization
4
4
5 def download_input
5 def download_input
6 send_data @testcase.input, type: 'text/plain', filename: "#{@testcase.problem.name}.#{@testcase.num}.in"
6 send_data @testcase.input, type: 'text/plain', filename: "#{@testcase.problem.name}.#{@testcase.num}.in"
7 end
7 end
8
8
9 def download_sol
9 def download_sol
10 send_data @testcase.sol, type: 'text/plain', filename: "#{@testcase.problem.name}.#{@testcase.num}.sol"
10 send_data @testcase.sol, type: 'text/plain', filename: "#{@testcase.problem.name}.#{@testcase.num}.sol"
11 end
11 end
12
12
13 + def show_problem
14 + @problem = Problem.includes(:testcases).find(params[:problem_id])
15 + unless @current_user.admin? or @problem.view_testcase
16 + flash[:error] = 'You cannot view the testcase of this problem'
17 + redirect_to :controller => 'main', :action => 'list'
18 + end
19 + end
20 +
13
21
14 private
22 private
15 # Use callbacks to share common setup or constraints between actions.
23 # Use callbacks to share common setup or constraints between actions.
16 def set_testcase
24 def set_testcase
17 @testcase = Testcase.find(params[:id])
25 @testcase = Testcase.find(params[:id])
18 end
26 end
19
27
20 # Only allow a trusted parameter "white list" through.
28 # Only allow a trusted parameter "white list" through.
21 def testcase_params
29 def testcase_params
22 params[:testcase]
30 params[:testcase]
23 end
31 end
24 end
32 end
@@ -175,25 +175,48
175 result = <<TITLEBAR
175 result = <<TITLEBAR
176 <div class="title">
176 <div class="title">
177 <table>
177 <table>
178 #{header}
178 #{header}
179 <tr>
179 <tr>
180 <td class="left-col">
180 <td class="left-col">
181 #{user.full_name}<br/>
181 #{user.full_name}<br/>
182 #{t 'title_bar.current_time'} #{format_short_time(Time.zone.now)}
182 #{t 'title_bar.current_time'} #{format_short_time(Time.zone.now)}
183 #{time_left}
183 #{time_left}
184 <br/>
184 <br/>
185 </td>
185 </td>
186 <td class="right-col">#{contest_name}</td>
186 <td class="right-col">#{contest_name}</td>
187 </tr>
187 </tr>
188 </table>
188 </table>
189 </div>
189 </div>
190 TITLEBAR
190 TITLEBAR
191 result.html_safe
191 result.html_safe
192 end
192 end
193
193
194 def markdown(text)
194 def markdown(text)
195 markdown = RDiscount.new(text)
195 markdown = RDiscount.new(text)
196 markdown.to_html.html_safe
196 markdown.to_html.html_safe
197 end
197 end
198
198
199 +
200 + BOOTSTRAP_FLASH_MSG = {
201 + success: 'alert-success',
202 + error: 'alert-danger',
203 + alert: 'alert-block',
204 + notice: 'alert-info'
205 + }
206 +
207 + def bootstrap_class_for(flash_type)
208 + BOOTSTRAP_FLASH_MSG.fetch(flash_type.to_sym, flash_type.to_s)
209 + end
210 +
211 + def flash_messages
212 + puts "flahs size = #{flash.count}"
213 + flash.each do |msg_type, message|
214 + concat(content_tag(:div, message, class: "alert #{bootstrap_class_for(msg_type)} fade in") do
215 + concat content_tag(:button, 'x', class: "close", data: { dismiss: 'alert' })
216 + concat message
217 + end)
218 + end
219 + nil
220 + end
221 +
199 end
222 end
@@ -1,15 +1,16
1 <!DOCTYPE html>
1 <!DOCTYPE html>
2 %html
2 %html
3 %head
3 %head
4 %title= GraderConfiguration['contest.name']
4 %title= GraderConfiguration['contest.name']
5 = stylesheet_link_tag "application", params[:controller], :media => "all"
5 = stylesheet_link_tag "application", params[:controller], :media => "all"
6 = javascript_include_tag "application", params[:controller]
6 = javascript_include_tag "application", params[:controller]
7 = csrf_meta_tags
7 = csrf_meta_tags
8 = content_for :header
8 = content_for :header
9 = yield :head
9 = yield :head
10
10
11 %body
11 %body
12 = render 'layouts/header'
12 = render 'layouts/header'
13
13
14 - = content_tag(:p,flash[:notice],class: 'alert alert-success') if flash[:notice]!=nil
14 + /= content_tag(:p,flash[:notice],class: 'alert alert-success') if flash[:notice]!=nil
15 + = flash_messages
15 = yield
16 = yield
@@ -1,35 +1,37
1 %b= GraderConfiguration['ui.front.welcome_message']
1 %b= GraderConfiguration['ui.front.welcome_message']
2 %br/
2 %br/
3
3
4 - if !@hidelogin
4 - if !@hidelogin
5 =t 'login.message'
5 =t 'login.message'
6 %br/
6 %br/
7 %br/
7 %br/
8
8
9 + - puts flash.inspect
9 - if flash[:notice]
10 - if flash[:notice]
10 %hr/
11 %hr/
11 %b= flash[:notice]
12 %b= flash[:notice]
13 + %b= haha
12 %hr/
14 %hr/
13
15
14 %div{ :style => "border: solid 1px gray; padding: 4px; background: #eeeeff;"}
16 %div{ :style => "border: solid 1px gray; padding: 4px; background: #eeeeff;"}
15 = form_tag login_login_path do
17 = form_tag login_login_path do
16 %table
18 %table
17 %tr
19 %tr
18 %td{:align => "right"}
20 %td{:align => "right"}
19 ="#{t 'login_label'}:"
21 ="#{t 'login_label'}:"
20 %td= text_field_tag 'login'
22 %td= text_field_tag 'login'
21 %tr
23 %tr
22 %td{:align => "right"}
24 %td{:align => "right"}
23 ="#{t 'password_label'}:"
25 ="#{t 'password_label'}:"
24 %td= password_field_tag
26 %td= password_field_tag
25 - unless GraderConfiguration['right.bypass_agreement']
27 - unless GraderConfiguration['right.bypass_agreement']
26 %tr
28 %tr
27 %td{:align => "right"}= check_box_tag 'accept_agree'
29 %td{:align => "right"}= check_box_tag 'accept_agree'
28 %td ยอมรับข้อตกลงการใช้งาน
30 %td ยอมรับข้อตกลงการใช้งาน
29
31
30 = submit_tag t('login.login_submit')
32 = submit_tag t('login.login_submit')
31 %br/
33 %br/
32
34
33 - if GraderConfiguration['system.online_registration']
35 - if GraderConfiguration['system.online_registration']
34 =t 'login.participation'
36 =t 'login.participation'
35 %b
37 %b
@@ -4,26 +4,26
4 - else
4 - else
5 - unless submission.graded_at
5 - unless submission.graded_at
6 = t 'main.submitted_at'
6 = t 'main.submitted_at'
7 = format_short_time(submission.submitted_at.localtime)
7 = format_short_time(submission.submitted_at.localtime)
8 - else
8 - else
9 %strong= t 'main.graded_at'
9 %strong= t 'main.graded_at'
10 = "#{format_short_time(submission.graded_at.localtime)} "
10 = "#{format_short_time(submission.graded_at.localtime)} "
11 %br
11 %br
12 - if GraderConfiguration['ui.show_score']
12 - if GraderConfiguration['ui.show_score']
13 %strong=t 'main.score'
13 %strong=t 'main.score'
14 = "#{(submission.points*100/submission.problem.full_score).to_i} "
14 = "#{(submission.points*100/submission.problem.full_score).to_i} "
15 = " ["
15 = " ["
16 %tt
16 %tt
17 = submission.grader_comment
17 = submission.grader_comment
18 = "]"
18 = "]"
19 %br
19 %br
20 %strong View:
20 %strong View:
21 - if GraderConfiguration.show_grading_result
21 - if GraderConfiguration.show_grading_result
22 = link_to '[detailed result]', :action => 'result', :id => submission.id
22 = link_to '[detailed result]', :action => 'result', :id => submission.id
23 /= link_to "#{t 'main.cmp_msg'}", {:action => 'compiler_msg', :id => submission.id}, {popup: true,class: 'btn btn-xs btn-info'}
23 /= link_to "#{t 'main.cmp_msg'}", {:action => 'compiler_msg', :id => submission.id}, {popup: true,class: 'btn btn-xs btn-info'}
24 = link_to "#{t 'main.cmp_msg'}", compiler_msg_submission_path(submission.id), {popup: true,remote: true,class: 'btn btn-xs btn-info'}
24 = link_to "#{t 'main.cmp_msg'}", compiler_msg_submission_path(submission.id), {popup: true,remote: true,class: 'btn btn-xs btn-info'}
25 = link_to "#{t 'main.src_link'}",{:action => 'source', :id => submission.id}, class: 'btn btn-xs btn-info'
25 = link_to "#{t 'main.src_link'}",{:action => 'source', :id => submission.id}, class: 'btn btn-xs btn-info'
26 = link_to "#{t 'main.submissions_link'}", problem_submissions_path(problem_id), class: 'btn btn-xs btn-info'
26 = link_to "#{t 'main.submissions_link'}", problem_submissions_path(problem_id), class: 'btn btn-xs btn-info'
27 - if GraderConfiguration.show_testcase
27 - if GraderConfiguration.show_testcase
28 - = link_to "testcases", show_testcase_problem_path(problem_id), class: 'btn btn-xs btn-info'
28 + = link_to "testcases", show_problem_testcases_path(problem_id), class: 'btn btn-xs btn-info'
29
29
@@ -5,46 +5,50
5 = link_to 'New problem', new_problem_path, class: 'btn btn-default btn-sm'
5 = link_to 'New problem', new_problem_path, class: 'btn btn-default btn-sm'
6 = link_to 'Manage problems', { action: 'manage'}, class: 'btn btn-default btn-sm'
6 = link_to 'Manage problems', { action: 'manage'}, class: 'btn btn-default btn-sm'
7 = link_to 'Import problems', {:action => 'import'}, class: 'btn btn-default btn-sm'
7 = link_to 'Import problems', {:action => 'import'}, class: 'btn btn-default btn-sm'
8 = link_to 'Turn off all problems', {:action => 'turn_all_off'}, class: 'btn btn-default btn-sm'
8 = link_to 'Turn off all problems', {:action => 'turn_all_off'}, class: 'btn btn-default btn-sm'
9 = link_to 'Turn on all problems', {:action => 'turn_all_on'}, class: 'btn btn-default btn-sm'
9 = link_to 'Turn on all problems', {:action => 'turn_all_on'}, class: 'btn btn-default btn-sm'
10 .submitbox
10 .submitbox
11 = form_tag :action => 'quick_create' do
11 = form_tag :action => 'quick_create' do
12 %b Quick New:
12 %b Quick New:
13 %label{:for => "problem_name"} Name
13 %label{:for => "problem_name"} Name
14 = text_field 'problem', 'name'
14 = text_field 'problem', 'name'
15 |
15 |
16 %label{:for => "problem_full_name"} Full name
16 %label{:for => "problem_full_name"} Full name
17 = text_field 'problem', 'full_name'
17 = text_field 'problem', 'full_name'
18 = submit_tag "Create"
18 = submit_tag "Create"
19 %table.table.table-condense.table-hover
19 %table.table.table-condense.table-hover
20 %thead
20 %thead
21 %th Name
21 %th Name
22 %th Full name
22 %th Full name
23 %th.text-right Full score
23 %th.text-right Full score
24 %th Date added
24 %th Date added
25 %th.text-center
25 %th.text-center
26 Avail?
26 Avail?
27 %sup{class: 'text-primary',data: {toggle: 'tooltip'}, title: 'Let user submits to this problem?' } [?]
27 %sup{class: 'text-primary',data: {toggle: 'tooltip'}, title: 'Let user submits to this problem?' } [?]
28 %th.text-center
28 %th.text-center
29 + View Data?
30 + %sup{class: 'text-primary',data: {toggle: 'tooltip'}, title: 'Let user view the testcase of this problem?' } [?]
31 + %th.text-center
29 Test?
32 Test?
30 %sup{class: 'text-primary',data: {toggle: 'tooltip'}, title: 'Let user uses test interface on this problem?' } [?]
33 %sup{class: 'text-primary',data: {toggle: 'tooltip'}, title: 'Let user uses test interface on this problem?' } [?]
31 - if GraderConfiguration.multicontests?
34 - if GraderConfiguration.multicontests?
32 %th Contests
35 %th Contests
33 - for problem in @problems
36 - for problem in @problems
34 %tr{:class => "#{(problem.available) ? "success" : "danger"}", :id => "prob-#{problem.id}", :name => "prob-#{problem.id}"}
37 %tr{:class => "#{(problem.available) ? "success" : "danger"}", :id => "prob-#{problem.id}", :name => "prob-#{problem.id}"}
35 - @problem=problem
38 - @problem=problem
36 %td= problem.name #in_place_editor_field :problem, :name, {}, :rows=>1
39 %td= problem.name #in_place_editor_field :problem, :name, {}, :rows=>1
37 %td= problem.full_name #in_place_editor_field :problem, :full_name, {}, :rows=>1
40 %td= problem.full_name #in_place_editor_field :problem, :full_name, {}, :rows=>1
38 %td.text-right= problem.full_score #in_place_editor_field :problem, :full_score, {}, :rows=>1
41 %td.text-right= problem.full_score #in_place_editor_field :problem, :full_score, {}, :rows=>1
39 %td= problem.date_added
42 %td= problem.date_added
40 %td= toggle_button(@problem.available?, toggle_problem_path(@problem), "problem-avail-#{@problem.id}")
43 %td= toggle_button(@problem.available?, toggle_problem_path(@problem), "problem-avail-#{@problem.id}")
44 + %td= toggle_button(@problem.view_testcase?, toggle_view_testcase_problem_path(@problem), "problem-view-testcase-#{@problem.id}")
41 %td= toggle_button(@problem.test_allowed?, toggle_test_problem_path(@problem), "problem-test-#{@problem.id}")
45 %td= toggle_button(@problem.test_allowed?, toggle_test_problem_path(@problem), "problem-test-#{@problem.id}")
42 - if GraderConfiguration.multicontests?
46 - if GraderConfiguration.multicontests?
43 %td
47 %td
44 = problem.contests.collect { |c| c.name }.join(', ')
48 = problem.contests.collect { |c| c.name }.join(', ')
45 %td= link_to 'Stat', {:action => 'stat', :id => problem.id}, class: 'btn btn-info btn-xs btn-block'
49 %td= link_to 'Stat', {:action => 'stat', :id => problem.id}, class: 'btn btn-info btn-xs btn-block'
46 %td= link_to 'Show', {:action => 'show', :id => problem}, class: 'btn btn-info btn-xs btn-block'
50 %td= link_to 'Show', {:action => 'show', :id => problem}, class: 'btn btn-info btn-xs btn-block'
47 %td= link_to 'Edit', {:action => 'edit', :id => problem}, class: 'btn btn-info btn-xs btn-block'
51 %td= link_to 'Edit', {:action => 'edit', :id => problem}, class: 'btn btn-info btn-xs btn-block'
48 %td= link_to 'Destroy', { :action => 'destroy', :id => problem }, :confirm => 'Are you sure?', :method => :delete, class: 'btn btn-danger btn-xs btn-block'
52 %td= link_to 'Destroy', { :action => 'destroy', :id => problem }, :confirm => 'Are you sure?', :method => :delete, class: 'btn btn-danger btn-xs btn-block'
49 %br/
53 %br/
50 = link_to '[New problem]', :action => 'new'
54 = link_to '[New problem]', :action => 'new'
@@ -1,61 +1,65
1 CafeGrader::Application.routes.draw do
1 CafeGrader::Application.routes.draw do
2 get "sources/direct_edit"
2 get "sources/direct_edit"
3
3
4 root :to => 'main#login'
4 root :to => 'main#login'
5
5
6 #logins
6 #logins
7 get 'login/login', to: 'login#login'
7 get 'login/login', to: 'login#login'
8
8
9 resources :contests
9 resources :contests
10
10
11 resources :sites
11 resources :sites
12
12
13 resources :announcements do
13 resources :announcements do
14 member do
14 member do
15 get 'toggle','toggle_front'
15 get 'toggle','toggle_front'
16 end
16 end
17 end
17 end
18
18
19 resources :problems do
19 resources :problems do
20 member do
20 member do
21 get 'toggle'
21 get 'toggle'
22 get 'toggle_test'
22 get 'toggle_test'
23 + get 'toggle_view_testcase'
23 get 'stat'
24 get 'stat'
24 - get 'show_testcase'
25 end
25 end
26 collection do
26 collection do
27 get 'turn_all_off'
27 get 'turn_all_off'
28 get 'turn_all_on'
28 get 'turn_all_on'
29 get 'import'
29 get 'import'
30 get 'manage'
30 get 'manage'
31 end
31 end
32
32
33 - resources :testcases, only: [] do
33 + end
34 - member do
34 +
35 - get 'download_input'
35 + resources :testcases, only: [] do
36 - get 'download_sol'
36 + member do
37 - end
37 + get 'download_input'
38 + get 'download_sol'
39 + end
40 + collection do
41 + get 'show_problem/:problem_id(/:test_num)' => 'testcases#show_problem', as: 'show_problem'
38 end
42 end
39 end
43 end
40
44
41 resources :grader_configuration, controller: 'configurations'
45 resources :grader_configuration, controller: 'configurations'
42
46
43 resources :users do
47 resources :users do
44 member do
48 member do
45 get 'toggle_activate', 'toggle_enable'
49 get 'toggle_activate', 'toggle_enable'
46 get 'stat'
50 get 'stat'
47 end
51 end
48 end
52 end
49
53
50 resources :submissions do
54 resources :submissions do
51 member do
55 member do
52 get 'download'
56 get 'download'
53 get 'compiler_msg'
57 get 'compiler_msg'
54 end
58 end
55 collection do
59 collection do
56 get 'prob/:problem_id', to: 'submissions#index', as: 'problem'
60 get 'prob/:problem_id', to: 'submissions#index', as: 'problem'
57 get 'direct_edit_problem/:problem_id', to: 'submissions#direct_edit_problem', as: 'direct_edit_problem'
61 get 'direct_edit_problem/:problem_id', to: 'submissions#direct_edit_problem', as: 'direct_edit_problem'
58 get 'get_latest_submission_status/:uid/:pid', to: 'submissions#get_latest_submission_status', as: 'get_latest_submission_status'
62 get 'get_latest_submission_status/:uid/:pid', to: 'submissions#get_latest_submission_status', as: 'get_latest_submission_status'
59 end
63 end
60 end
64 end
61
65
@@ -1,280 +1,281
1 # encoding: UTF-8
1 # encoding: UTF-8
2 # This file is auto-generated from the current state of the database. Instead
2 # This file is auto-generated from the current state of the database. Instead
3 # of editing this file, please use the migrations feature of Active Record to
3 # of editing this file, please use the migrations feature of Active Record to
4 # incrementally modify your database, and then regenerate this schema definition.
4 # incrementally modify your database, and then regenerate this schema definition.
5 #
5 #
6 # Note that this schema.rb definition is the authoritative source for your
6 # Note that this schema.rb definition is the authoritative source for your
7 # database schema. If you need to create the application database on another
7 # database schema. If you need to create the application database on another
8 # system, you should be using db:schema:load, not running all the migrations
8 # system, you should be using db:schema:load, not running all the migrations
9 # from scratch. The latter is a flawed and unsustainable approach (the more migrations
9 # from scratch. The latter is a flawed and unsustainable approach (the more migrations
10 # you'll amass, the slower it'll run and the greater likelihood for issues).
10 # you'll amass, the slower it'll run and the greater likelihood for issues).
11 #
11 #
12 # It's strongly recommended that you check this file into your version control system.
12 # It's strongly recommended that you check this file into your version control system.
13
13
14 - ActiveRecord::Schema.define(version: 20170123162543) do
14 + ActiveRecord::Schema.define(version: 20170124024527) do
15
15
16 create_table "announcements", force: :cascade do |t|
16 create_table "announcements", force: :cascade do |t|
17 t.string "author", limit: 255
17 t.string "author", limit: 255
18 - t.text "body", limit: 16777215
18 + t.text "body", limit: 65535
19 t.boolean "published"
19 t.boolean "published"
20 - t.datetime "created_at", null: false
20 + t.datetime "created_at", null: false
21 - t.datetime "updated_at", null: false
21 + t.datetime "updated_at", null: false
22 - t.boolean "frontpage", default: false
22 + t.boolean "frontpage", default: false
23 - t.boolean "contest_only", default: false
23 + t.boolean "contest_only", default: false
24 t.string "title", limit: 255
24 t.string "title", limit: 255
25 t.string "notes", limit: 255
25 t.string "notes", limit: 255
26 end
26 end
27
27
28 create_table "contests", force: :cascade do |t|
28 create_table "contests", force: :cascade do |t|
29 t.string "title", limit: 255
29 t.string "title", limit: 255
30 t.boolean "enabled"
30 t.boolean "enabled"
31 t.datetime "created_at", null: false
31 t.datetime "created_at", null: false
32 t.datetime "updated_at", null: false
32 t.datetime "updated_at", null: false
33 t.string "name", limit: 255
33 t.string "name", limit: 255
34 end
34 end
35
35
36 create_table "contests_problems", id: false, force: :cascade do |t|
36 create_table "contests_problems", id: false, force: :cascade do |t|
37 t.integer "contest_id", limit: 4
37 t.integer "contest_id", limit: 4
38 t.integer "problem_id", limit: 4
38 t.integer "problem_id", limit: 4
39 end
39 end
40
40
41 create_table "contests_users", id: false, force: :cascade do |t|
41 create_table "contests_users", id: false, force: :cascade do |t|
42 t.integer "contest_id", limit: 4
42 t.integer "contest_id", limit: 4
43 t.integer "user_id", limit: 4
43 t.integer "user_id", limit: 4
44 end
44 end
45
45
46 create_table "countries", force: :cascade do |t|
46 create_table "countries", force: :cascade do |t|
47 t.string "name", limit: 255
47 t.string "name", limit: 255
48 t.datetime "created_at", null: false
48 t.datetime "created_at", null: false
49 t.datetime "updated_at", null: false
49 t.datetime "updated_at", null: false
50 end
50 end
51
51
52 create_table "descriptions", force: :cascade do |t|
52 create_table "descriptions", force: :cascade do |t|
53 - t.text "body", limit: 16777215
53 + t.text "body", limit: 65535
54 t.boolean "markdowned"
54 t.boolean "markdowned"
55 - t.datetime "created_at", null: false
55 + t.datetime "created_at", null: false
56 - t.datetime "updated_at", null: false
56 + t.datetime "updated_at", null: false
57 end
57 end
58
58
59 create_table "grader_configurations", force: :cascade do |t|
59 create_table "grader_configurations", force: :cascade do |t|
60 t.string "key", limit: 255
60 t.string "key", limit: 255
61 t.string "value_type", limit: 255
61 t.string "value_type", limit: 255
62 t.string "value", limit: 255
62 t.string "value", limit: 255
63 - t.datetime "created_at", null: false
63 + t.datetime "created_at", null: false
64 - t.datetime "updated_at", null: false
64 + t.datetime "updated_at", null: false
65 - t.text "description", limit: 16777215
65 + t.text "description", limit: 65535
66 end
66 end
67
67
68 create_table "grader_processes", force: :cascade do |t|
68 create_table "grader_processes", force: :cascade do |t|
69 t.string "host", limit: 255
69 t.string "host", limit: 255
70 t.integer "pid", limit: 4
70 t.integer "pid", limit: 4
71 t.string "mode", limit: 255
71 t.string "mode", limit: 255
72 t.boolean "active"
72 t.boolean "active"
73 t.datetime "created_at", null: false
73 t.datetime "created_at", null: false
74 t.datetime "updated_at", null: false
74 t.datetime "updated_at", null: false
75 t.integer "task_id", limit: 4
75 t.integer "task_id", limit: 4
76 t.string "task_type", limit: 255
76 t.string "task_type", limit: 255
77 t.boolean "terminated"
77 t.boolean "terminated"
78 end
78 end
79
79
80 add_index "grader_processes", ["host", "pid"], name: "index_grader_processes_on_ip_and_pid", using: :btree
80 add_index "grader_processes", ["host", "pid"], name: "index_grader_processes_on_ip_and_pid", using: :btree
81
81
82 create_table "heart_beats", force: :cascade do |t|
82 create_table "heart_beats", force: :cascade do |t|
83 t.integer "user_id", limit: 4
83 t.integer "user_id", limit: 4
84 t.string "ip_address", limit: 255
84 t.string "ip_address", limit: 255
85 t.datetime "created_at", null: false
85 t.datetime "created_at", null: false
86 t.datetime "updated_at", null: false
86 t.datetime "updated_at", null: false
87 t.string "status", limit: 255
87 t.string "status", limit: 255
88 end
88 end
89
89
90 add_index "heart_beats", ["updated_at"], name: "index_heart_beats_on_updated_at", using: :btree
90 add_index "heart_beats", ["updated_at"], name: "index_heart_beats_on_updated_at", using: :btree
91
91
92 create_table "languages", force: :cascade do |t|
92 create_table "languages", force: :cascade do |t|
93 t.string "name", limit: 10
93 t.string "name", limit: 10
94 t.string "pretty_name", limit: 255
94 t.string "pretty_name", limit: 255
95 t.string "ext", limit: 10
95 t.string "ext", limit: 10
96 t.string "common_ext", limit: 255
96 t.string "common_ext", limit: 255
97 end
97 end
98
98
99 create_table "logins", force: :cascade do |t|
99 create_table "logins", force: :cascade do |t|
100 t.integer "user_id", limit: 4
100 t.integer "user_id", limit: 4
101 t.string "ip_address", limit: 255
101 t.string "ip_address", limit: 255
102 t.datetime "created_at", null: false
102 t.datetime "created_at", null: false
103 t.datetime "updated_at", null: false
103 t.datetime "updated_at", null: false
104 end
104 end
105
105
106 create_table "messages", force: :cascade do |t|
106 create_table "messages", force: :cascade do |t|
107 t.integer "sender_id", limit: 4
107 t.integer "sender_id", limit: 4
108 t.integer "receiver_id", limit: 4
108 t.integer "receiver_id", limit: 4
109 t.integer "replying_message_id", limit: 4
109 t.integer "replying_message_id", limit: 4
110 - t.text "body", limit: 16777215
110 + t.text "body", limit: 65535
111 t.boolean "replied"
111 t.boolean "replied"
112 - t.datetime "created_at", null: false
112 + t.datetime "created_at", null: false
113 - t.datetime "updated_at", null: false
113 + t.datetime "updated_at", null: false
114 end
114 end
115
115
116 create_table "problems", force: :cascade do |t|
116 create_table "problems", force: :cascade do |t|
117 t.string "name", limit: 30
117 t.string "name", limit: 30
118 t.string "full_name", limit: 255
118 t.string "full_name", limit: 255
119 t.integer "full_score", limit: 4
119 t.integer "full_score", limit: 4
120 t.date "date_added"
120 t.date "date_added"
121 t.boolean "available"
121 t.boolean "available"
122 t.string "url", limit: 255
122 t.string "url", limit: 255
123 t.integer "description_id", limit: 4
123 t.integer "description_id", limit: 4
124 t.boolean "test_allowed"
124 t.boolean "test_allowed"
125 t.boolean "output_only"
125 t.boolean "output_only"
126 t.string "description_filename", limit: 255
126 t.string "description_filename", limit: 255
127 + t.boolean "view_testcase"
127 end
128 end
128
129
129 create_table "rights", force: :cascade do |t|
130 create_table "rights", force: :cascade do |t|
130 t.string "name", limit: 255
131 t.string "name", limit: 255
131 t.string "controller", limit: 255
132 t.string "controller", limit: 255
132 t.string "action", limit: 255
133 t.string "action", limit: 255
133 end
134 end
134
135
135 create_table "rights_roles", id: false, force: :cascade do |t|
136 create_table "rights_roles", id: false, force: :cascade do |t|
136 t.integer "right_id", limit: 4
137 t.integer "right_id", limit: 4
137 t.integer "role_id", limit: 4
138 t.integer "role_id", limit: 4
138 end
139 end
139
140
140 add_index "rights_roles", ["role_id"], name: "index_rights_roles_on_role_id", using: :btree
141 add_index "rights_roles", ["role_id"], name: "index_rights_roles_on_role_id", using: :btree
141
142
142 create_table "roles", force: :cascade do |t|
143 create_table "roles", force: :cascade do |t|
143 t.string "name", limit: 255
144 t.string "name", limit: 255
144 end
145 end
145
146
146 create_table "roles_users", id: false, force: :cascade do |t|
147 create_table "roles_users", id: false, force: :cascade do |t|
147 t.integer "role_id", limit: 4
148 t.integer "role_id", limit: 4
148 t.integer "user_id", limit: 4
149 t.integer "user_id", limit: 4
149 end
150 end
150
151
151 add_index "roles_users", ["user_id"], name: "index_roles_users_on_user_id", using: :btree
152 add_index "roles_users", ["user_id"], name: "index_roles_users_on_user_id", using: :btree
152
153
153 create_table "sessions", force: :cascade do |t|
154 create_table "sessions", force: :cascade do |t|
154 t.string "session_id", limit: 255
155 t.string "session_id", limit: 255
155 - t.text "data", limit: 16777215
156 + t.text "data", limit: 65535
156 t.datetime "updated_at"
157 t.datetime "updated_at"
157 end
158 end
158
159
159 add_index "sessions", ["session_id"], name: "index_sessions_on_session_id", using: :btree
160 add_index "sessions", ["session_id"], name: "index_sessions_on_session_id", using: :btree
160 add_index "sessions", ["updated_at"], name: "index_sessions_on_updated_at", using: :btree
161 add_index "sessions", ["updated_at"], name: "index_sessions_on_updated_at", using: :btree
161
162
162 create_table "sites", force: :cascade do |t|
163 create_table "sites", force: :cascade do |t|
163 t.string "name", limit: 255
164 t.string "name", limit: 255
164 t.boolean "started"
165 t.boolean "started"
165 t.datetime "start_time"
166 t.datetime "start_time"
166 t.datetime "created_at", null: false
167 t.datetime "created_at", null: false
167 t.datetime "updated_at", null: false
168 t.datetime "updated_at", null: false
168 t.integer "country_id", limit: 4
169 t.integer "country_id", limit: 4
169 t.string "password", limit: 255
170 t.string "password", limit: 255
170 end
171 end
171
172
172 create_table "submission_view_logs", force: :cascade do |t|
173 create_table "submission_view_logs", force: :cascade do |t|
173 t.integer "user_id", limit: 4
174 t.integer "user_id", limit: 4
174 t.integer "submission_id", limit: 4
175 t.integer "submission_id", limit: 4
175 t.datetime "created_at", null: false
176 t.datetime "created_at", null: false
176 t.datetime "updated_at", null: false
177 t.datetime "updated_at", null: false
177 end
178 end
178
179
179 create_table "submissions", force: :cascade do |t|
180 create_table "submissions", force: :cascade do |t|
180 t.integer "user_id", limit: 4
181 t.integer "user_id", limit: 4
181 t.integer "problem_id", limit: 4
182 t.integer "problem_id", limit: 4
182 t.integer "language_id", limit: 4
183 t.integer "language_id", limit: 4
183 - t.text "source", limit: 16777215
184 + t.text "source", limit: 65535
184 t.binary "binary", limit: 65535
185 t.binary "binary", limit: 65535
185 t.datetime "submitted_at"
186 t.datetime "submitted_at"
186 t.datetime "compiled_at"
187 t.datetime "compiled_at"
187 - t.text "compiler_message", limit: 16777215
188 + t.text "compiler_message", limit: 65535
188 t.datetime "graded_at"
189 t.datetime "graded_at"
189 t.integer "points", limit: 4
190 t.integer "points", limit: 4
190 - t.text "grader_comment", limit: 16777215
191 + t.text "grader_comment", limit: 65535
191 t.integer "number", limit: 4
192 t.integer "number", limit: 4
192 t.string "source_filename", limit: 255
193 t.string "source_filename", limit: 255
193 t.float "max_runtime", limit: 24
194 t.float "max_runtime", limit: 24
194 t.integer "peak_memory", limit: 4
195 t.integer "peak_memory", limit: 4
195 t.integer "effective_code_length", limit: 4
196 t.integer "effective_code_length", limit: 4
196 t.string "ip_address", limit: 255
197 t.string "ip_address", limit: 255
197 end
198 end
198
199
199 add_index "submissions", ["user_id", "problem_id", "number"], name: "index_submissions_on_user_id_and_problem_id_and_number", unique: true, using: :btree
200 add_index "submissions", ["user_id", "problem_id", "number"], name: "index_submissions_on_user_id_and_problem_id_and_number", unique: true, using: :btree
200 add_index "submissions", ["user_id", "problem_id"], name: "index_submissions_on_user_id_and_problem_id", using: :btree
201 add_index "submissions", ["user_id", "problem_id"], name: "index_submissions_on_user_id_and_problem_id", using: :btree
201
202
202 create_table "tasks", force: :cascade do |t|
203 create_table "tasks", force: :cascade do |t|
203 t.integer "submission_id", limit: 4
204 t.integer "submission_id", limit: 4
204 t.datetime "created_at"
205 t.datetime "created_at"
205 t.integer "status", limit: 4
206 t.integer "status", limit: 4
206 t.datetime "updated_at"
207 t.datetime "updated_at"
207 end
208 end
208
209
209 create_table "test_pairs", force: :cascade do |t|
210 create_table "test_pairs", force: :cascade do |t|
210 t.integer "problem_id", limit: 4
211 t.integer "problem_id", limit: 4
211 - t.text "input", limit: 4294967295
212 + t.text "input", limit: 16777215
212 - t.text "solution", limit: 4294967295
213 + t.text "solution", limit: 16777215
213 - t.datetime "created_at", null: false
214 + t.datetime "created_at", null: false
214 - t.datetime "updated_at", null: false
215 + t.datetime "updated_at", null: false
215 end
216 end
216
217
217 create_table "test_requests", force: :cascade do |t|
218 create_table "test_requests", force: :cascade do |t|
218 t.integer "user_id", limit: 4
219 t.integer "user_id", limit: 4
219 t.integer "problem_id", limit: 4
220 t.integer "problem_id", limit: 4
220 t.integer "submission_id", limit: 4
221 t.integer "submission_id", limit: 4
221 t.string "input_file_name", limit: 255
222 t.string "input_file_name", limit: 255
222 t.string "output_file_name", limit: 255
223 t.string "output_file_name", limit: 255
223 t.string "running_stat", limit: 255
224 t.string "running_stat", limit: 255
224 t.integer "status", limit: 4
225 t.integer "status", limit: 4
225 - t.datetime "updated_at", null: false
226 + t.datetime "updated_at", null: false
226 t.datetime "submitted_at"
227 t.datetime "submitted_at"
227 t.datetime "compiled_at"
228 t.datetime "compiled_at"
228 - t.text "compiler_message", limit: 16777215
229 + t.text "compiler_message", limit: 65535
229 t.datetime "graded_at"
230 t.datetime "graded_at"
230 t.string "grader_comment", limit: 255
231 t.string "grader_comment", limit: 255
231 - t.datetime "created_at", null: false
232 + t.datetime "created_at", null: false
232 t.float "running_time", limit: 24
233 t.float "running_time", limit: 24
233 t.string "exit_status", limit: 255
234 t.string "exit_status", limit: 255
234 t.integer "memory_usage", limit: 4
235 t.integer "memory_usage", limit: 4
235 end
236 end
236
237
237 add_index "test_requests", ["user_id", "problem_id"], name: "index_test_requests_on_user_id_and_problem_id", using: :btree
238 add_index "test_requests", ["user_id", "problem_id"], name: "index_test_requests_on_user_id_and_problem_id", using: :btree
238
239
239 create_table "testcases", force: :cascade do |t|
240 create_table "testcases", force: :cascade do |t|
240 t.integer "problem_id", limit: 4
241 t.integer "problem_id", limit: 4
241 t.integer "num", limit: 4
242 t.integer "num", limit: 4
242 t.integer "group", limit: 4
243 t.integer "group", limit: 4
243 t.integer "score", limit: 4
244 t.integer "score", limit: 4
244 t.text "input", limit: 4294967295
245 t.text "input", limit: 4294967295
245 t.text "sol", limit: 4294967295
246 t.text "sol", limit: 4294967295
246 - t.datetime "created_at", null: false
247 + t.datetime "created_at"
247 - t.datetime "updated_at", null: false
248 + t.datetime "updated_at"
248 end
249 end
249
250
250 add_index "testcases", ["problem_id"], name: "index_testcases_on_problem_id", using: :btree
251 add_index "testcases", ["problem_id"], name: "index_testcases_on_problem_id", using: :btree
251
252
252 create_table "user_contest_stats", force: :cascade do |t|
253 create_table "user_contest_stats", force: :cascade do |t|
253 t.integer "user_id", limit: 4
254 t.integer "user_id", limit: 4
254 t.datetime "started_at"
255 t.datetime "started_at"
255 t.datetime "created_at", null: false
256 t.datetime "created_at", null: false
256 t.datetime "updated_at", null: false
257 t.datetime "updated_at", null: false
257 t.boolean "forced_logout"
258 t.boolean "forced_logout"
258 end
259 end
259
260
260 create_table "users", force: :cascade do |t|
261 create_table "users", force: :cascade do |t|
261 t.string "login", limit: 50
262 t.string "login", limit: 50
262 t.string "full_name", limit: 255
263 t.string "full_name", limit: 255
263 t.string "hashed_password", limit: 255
264 t.string "hashed_password", limit: 255
264 t.string "salt", limit: 5
265 t.string "salt", limit: 5
265 t.string "alias", limit: 255
266 t.string "alias", limit: 255
266 t.string "email", limit: 255
267 t.string "email", limit: 255
267 t.integer "site_id", limit: 4
268 t.integer "site_id", limit: 4
268 t.integer "country_id", limit: 4
269 t.integer "country_id", limit: 4
269 t.boolean "activated", default: false
270 t.boolean "activated", default: false
270 t.datetime "created_at"
271 t.datetime "created_at"
271 t.datetime "updated_at"
272 t.datetime "updated_at"
272 - t.string "section", limit: 255
273 t.boolean "enabled", default: true
273 t.boolean "enabled", default: true
274 t.string "remark", limit: 255
274 t.string "remark", limit: 255
275 t.string "last_ip", limit: 255
275 t.string "last_ip", limit: 255
276 + t.string "section", limit: 255
276 end
277 end
277
278
278 add_index "users", ["login"], name: "index_users_on_login", unique: true, using: :btree
279 add_index "users", ["login"], name: "index_users_on_login", unique: true, using: :btree
279
280
280 end
281 end
deleted file
You need to be logged in to leave comments. Login now