Description:
add model solution
Commit status:
[Not Reviewed]
References:
Comments:
0 Commit comments 0 Inline Comments
Unresolved TODOs:
There are no unresolved TODOs
Add another comment

r854:14d6c4fb29b0 - - 12 files changed: 225 inserted, 138 deleted

@@ -0,0 +1,6
1 + class AddTypeToSubmission < ActiveRecord::Migration[7.0]
2 + def change
3 + add_column :submissions, :tag, :integer, default: 0
4 + add_column :problems, :difficulty, :integer
5 + end
6 + end
@@ -36,12 +36,23
36 unauthorized_redirect
36 unauthorized_redirect
37 return false
37 return false
38 end
38 end
39 return true
39 return true
40 end
40 end
41
41
42 + #admin always count as every roles
43 + def role_authorization(roles)
44 + return false unless check_valid_login
45 + user = User.find(session[:user_id])
46 + return true if user.admin?
47 + roles.each do |r|
48 + return true if user.has_role?(r)
49 + end
50 + unauthorized_redirect
51 + end
52 +
42 def authorization_by_roles(allowed_roles)
53 def authorization_by_roles(allowed_roles)
43 return false unless check_valid_login
54 return false unless check_valid_login
44 unless @current_user.roles.detect { |role| allowed_roles.member?(role.name) }
55 unless @current_user.roles.detect { |role| allowed_roles.member?(role.name) }
45 unauthorized_redirect
56 unauthorized_redirect
46 return false
57 return false
47 end
58 end
@@ -68,13 +68,13
68 @submission.source = params[:editor_text]
68 @submission.source = params[:editor_text]
69 @submission.source_filename = "live_edit.#{language.ext}"
69 @submission.source_filename = "live_edit.#{language.ext}"
70 @submission.language = language
70 @submission.language = language
71 end
71 end
72
72
73 @submission.submitted_at = Time.new.gmtime
73 @submission.submitted_at = Time.new.gmtime
74 - @submission.ip_address = request.remote_ip
74 + @submission.ip_address = cookies.encrypted[:uuid]
75
75
76 if @current_user.admin? == false && GraderConfiguration.time_limit_mode? && @current_user.contest_finished?
76 if @current_user.admin? == false && GraderConfiguration.time_limit_mode? && @current_user.contest_finished?
77 @submission.errors.add(:base,"The contest is over.")
77 @submission.errors.add(:base,"The contest is over.")
78 prepare_list_information
78 prepare_list_information
79 render :action => 'list' and return
79 render :action => 'list' and return
80 end
80 end
@@ -231,22 +231,27
231 return
231 return
232 end
232 end
233 end
233 end
234
234
235 return unless @problem
235 return unless @problem
236
236
237 + #model submisssion
238 + @model_subs = Submission.where(problem: @problem,tag: Submission.tags[:model])
239 +
240 +
241 + #calculate best submission
237 @by_lang = {} #aggregrate by language
242 @by_lang = {} #aggregrate by language
238
243
239 range =65
244 range =65
240 - @histogram = { data: Array.new(range,0), summary: {} }
245 + #@histogram = { data: Array.new(range,0), summary: {} }
241 @summary = {count: 0, solve: 0, attempt: 0}
246 @summary = {count: 0, solve: 0, attempt: 0}
242 user = Hash.new(0)
247 user = Hash.new(0)
243 Submission.where(problem_id: @problem.id).find_each do |sub|
248 Submission.where(problem_id: @problem.id).find_each do |sub|
244 #histogram
249 #histogram
245 d = (DateTime.now.in_time_zone - sub.submitted_at) / 24 / 60 / 60
250 d = (DateTime.now.in_time_zone - sub.submitted_at) / 24 / 60 / 60
246 - @histogram[:data][d.to_i] += 1 if d < range
251 + #@histogram[:data][d.to_i] += 1 if d < range
247
252
248 next unless sub.points
253 next unless sub.points
249 @summary[:count] += 1
254 @summary[:count] += 1
250 user[sub.user_id] = [user[sub.user_id], (sub.points >= @problem.full_score) ? 1 : 0].max
255 user[sub.user_id] = [user[sub.user_id], (sub.points >= @problem.full_score) ? 1 : 0].max
251
256
252 lang = Language.find_by_id(sub.language_id)
257 lang = Language.find_by_id(sub.language_id)
@@ -308,15 +313,19
308 @best[:first] = prop[:first]
313 @best[:first] = prop[:first]
309 @best[:first][:lang] = lang
314 @best[:first][:lang] = lang
310 end
315 end
311 end
316 end
312 end
317 end
313
318
314 - @histogram[:summary][:max] = [@histogram[:data].max,1].max
319 + #@histogram[:summary][:max] = [@histogram[:data].max,1].max
315 @summary[:attempt] = user.count
320 @summary[:attempt] = user.count
316 user.each_value { |v| @summary[:solve] += 1 if v == 1 }
321 user.each_value { |v| @summary[:solve] += 1 if v == 1 }
322 +
323 +
324 + #for new graph
325 + @chart_dataset = @problem.get_jschart_history.to_json.html_safe
317 end
326 end
318
327
319 def stuck #report struggling user,problem
328 def stuck #report struggling user,problem
320 # init
329 # init
321 user,problem = nil
330 user,problem = nil
322 solve = true
331 solve = true
@@ -1,10 +1,11
1 class SubmissionsController < ApplicationController
1 class SubmissionsController < ApplicationController
2 + before_action :set_submission, only: [:show,:download,:compiler_msg,:rejudge,:set_tag, :edit]
2 before_action :check_valid_login
3 before_action :check_valid_login
3 before_action :submission_authorization, only: [:show, :download, :edit]
4 before_action :submission_authorization, only: [:show, :download, :edit]
4 - before_action :admin_authorization, only: [:rejudge]
5 + before_action only: [:rejudge, :set_tag] do role_authorization([:ta]) end
5
6
6 # GET /submissions
7 # GET /submissions
7 # GET /submissions.json
8 # GET /submissions.json
8 # Show problem selection and user's submission of that problem
9 # Show problem selection and user's submission of that problem
9 def index
10 def index
10 @user = @current_user
11 @user = @current_user
@@ -24,28 +25,24
24 end
25 end
25 end
26 end
26
27
27 # GET /submissions/1
28 # GET /submissions/1
28 # GET /submissions/1.json
29 # GET /submissions/1.json
29 def show
30 def show
30 - @submission = Submission.find(params[:id])
31 -
32 #log the viewing
31 #log the viewing
33 user = User.find(session[:user_id])
32 user = User.find(session[:user_id])
34 SubmissionViewLog.create(user_id: session[:user_id],submission_id: @submission.id) unless user.admin?
33 SubmissionViewLog.create(user_id: session[:user_id],submission_id: @submission.id) unless user.admin?
35
34
36 @task = @submission.task
35 @task = @submission.task
37 end
36 end
38
37
39 def download
38 def download
40 - @submission = Submission.find(params[:id])
41 send_data(@submission.source, {:filename => @submission.download_filename, :type => 'text/plain'})
39 send_data(@submission.source, {:filename => @submission.download_filename, :type => 'text/plain'})
42 end
40 end
43
41
44 def compiler_msg
42 def compiler_msg
45 - @submission = Submission.find(params[:id])
46 respond_to do |format|
43 respond_to do |format|
47 format.js
44 format.js
48 end
45 end
49 end
46 end
50
47
51 #on-site new submission on specific problem
48 #on-site new submission on specific problem
@@ -62,13 +59,12
62 end
59 end
63 render 'edit'
60 render 'edit'
64 end
61 end
65
62
66 # GET /submissions/1/edit
63 # GET /submissions/1/edit
67 def edit
64 def edit
68 - @submission = Submission.find(params[:id])
69 @source = @submission.source.to_s
65 @source = @submission.source.to_s
70 @problem = @submission.problem
66 @problem = @submission.problem
71 @lang_id = @submission.language.id
67 @lang_id = @submission.language.id
72 end
68 end
73
69
74
70
@@ -79,20 +75,24
79 format.js
75 format.js
80 end
76 end
81 end
77 end
82
78
83 # GET /submissions/:id/rejudge
79 # GET /submissions/:id/rejudge
84 def rejudge
80 def rejudge
85 - @submission = Submission.find(params[:id])
86 @task = @submission.task
81 @task = @submission.task
87 @task.status_inqueue! if @task
82 @task.status_inqueue! if @task
88 respond_to do |format|
83 respond_to do |format|
89 format.js
84 format.js
90 end
85 end
91 end
86 end
92
87
88 + def set_tag
89 + @submission.update(tag: params[:tag])
90 + redirect_to @submission
91 + end
92 +
93 protected
93 protected
94
94
95 def submission_authorization
95 def submission_authorization
96 #admin always has privileged
96 #admin always has privileged
97 return true if @current_user.admin?
97 return true if @current_user.admin?
98 return true if @current_user.has_role?('ta') && (['show','download'].include? action_name)
98 return true if @current_user.has_role?('ta') && (['show','download'].include? action_name)
@@ -104,8 +104,12
104
104
105 #default to NO
105 #default to NO
106 unauthorized_redirect
106 unauthorized_redirect
107 return false
107 return false
108 end
108 end
109
109
110 + def set_submission
111 + @submission = Submission.find(params[:id])
112 + end
113 +
110
114
111 end
115 end
@@ -21,12 +21,34
21
21
22 scope :available, -> { where(available: true) }
22 scope :available, -> { where(available: true) }
23
23
24 DEFAULT_TIME_LIMIT = 1
24 DEFAULT_TIME_LIMIT = 1
25 DEFAULT_MEMORY_LIMIT = 32
25 DEFAULT_MEMORY_LIMIT = 32
26
26
27 + def get_jschart_history
28 + start = 4.month.ago.beginning_of_day
29 + start_date = start.to_date
30 + count = Submission.where(problem: self).where('submitted_at >= ?', start).group('DATE(submitted_at)').count
31 + i = 0
32 + label = []
33 + value = []
34 + while (start_date + i < Time.zone.now.to_date)
35 + if (start_date+i).day == 1
36 + #label << (start_date+i).strftime("%d %b %Y")
37 + #label << (start_date+i).strftime("%d")
38 + else
39 + #label << ' '
40 + #label << (start_date+i).strftime("%d")
41 + end
42 + label << (start_date+i).strftime("%d-%b")
43 + value << (count[start_date+i] || 0)
44 + i+=1
45 + end
46 + return {labels: label,datasets: [label:'sub',data: value, backgroundColor: 'rgba(54, 162, 235, 0.2)', borderColor: 'rgb(75, 192, 192)']}
47 + end
48 +
27 def self.available_problems
49 def self.available_problems
28 available.order(date_added: :desc).order(:name)
50 available.order(date_added: :desc).order(:name)
29 #Problem.available.all(:order => "date_added DESC, name ASC")
51 #Problem.available.all(:order => "date_added DESC, name ASC")
30 end
52 end
31
53
32 def self.create_from_import_form_params(params, old_problem=nil)
54 def self.create_from_import_form_params(params, old_problem=nil)
@@ -1,8 +1,10
1 class Submission < ActiveRecord::Base
1 class Submission < ActiveRecord::Base
2
2
3 + enum tag: {default: 0, model: 1}, _prefix: true
4 +
3 belongs_to :language
5 belongs_to :language
4 belongs_to :problem
6 belongs_to :problem
5 belongs_to :user
7 belongs_to :user
6
8
7 before_validation :assign_problem
9 before_validation :assign_problem
8 before_validation :assign_language
10 before_validation :assign_language
@@ -21,97 +21,97
21 word-wrap: break-word;
21 word-wrap: break-word;
22 z-index: 9999;
22 z-index: 9999;
23 overflow: auto;
23 overflow: auto;
24 }
24 }
25
25
26
26
27 - .container
27 + .container-fluid
28 + .row
29 + .col-md-8
30 + .card
31 + .card-body
32 + %h2.card-title Submission History
33 + %canvas#chart{height: '50px'}
34 +
35 + .col-md-4
36 + .card
37 + .card-body
38 + %h2.card-title General Info
39 + .row
40 + .col-sm-6
41 + Subs
42 + .col-sm-6
43 + = @summary[:count]
44 + .row
45 + .col-sm-6
46 + Solved/Attempted User
47 + .col-sm-6
48 + #{@summary[:solve]}/#{@summary[:attempt]} (#{(@summary[:solve]*100.0/@summary[:attempt]).round(1)}%)
28 .row
49 .row
29 .col-md-4
50 .col-md-4
30 - %h2 Overall Stat
51 + .card
52 + .card-body
53 + %h2.card-title Model submission
31 %table.table.table-hover
54 %table.table.table-hover
32 %thead
55 %thead
33 %tr
56 %tr
34 - %th
57 + %th #Sub
35 - %th
58 + %th Author
36 %tbody
59 %tbody
37 - %tr
60 + - @model_subs.each do |sub|
38 - %td.info_param Submissions
39 - %td= @summary[:count]
40 - %tr
41 - %td.info_param Solved/Attempted User
42 - %td #{@summary[:solve]}/#{@summary[:attempt]} (#{(@summary[:solve]*100.0/@summary[:attempt]).round(1)}%)
43 - - if @best
44 - %tr
45 - %td.info_param Best Runtime
46 - %td
47 - by #{link_to @best[:runtime][:user], stat_user_path(@best[:runtime][:user_id])}
48 - %br
49 - using <span class="text-success">#{@best[:runtime][:lang]}</span>
50 - %br
51 - with <span class="text-success">#{@best[:runtime][:value] * 1000} milliseconds</span>
52 - %br
53 - at submission
54 - = link_to "#" + @best[:runtime][:sub_id].to_s, submission_path(@best[:runtime][:sub_id])
55 -
56 %tr
61 %tr
57 - %td.info_param
62 + %td= link_to "##{sub.id}", submission_path(sub)
58 - Best Memory Usage
63 + %td= sub.user.full_name
59 - %sup{ id: "xmem_remark",
60 - style: "position:relative; color: blue;",
61 - data: {toggle: 'tooltip', placement: 'top', animation: 'false', delay: 20},
62 - title: "This counts only for submission with 100% score. Right now, java is excluded from memory usage competition. (Because it always uses 2GB memory...)"}
63 - [?]
64 - %td
65 - by #{link_to @best[:memory][:user], stat_user_path(@best[:memory][:user_id])}
66 - %br
67 - using <span class="text-success">#{@best[:memory][:lang]}</span>
68 - %br
69 - with <span class="text-success">#{number_with_delimiter(@best[:memory][:value])} kbytes </span>
70 - %br
71 - at submission
72 - = link_to "#" + @best[:memory][:sub_id].to_s, submission_path(@best[:memory][:sub_id])
73 -
74 - %tr
75 - %td.info_param Shortest Code
76 - %td
77 - by #{link_to @best[:length][:user], stat_user_path(@best[:length][:user_id])}
78 - %br
79 - using <span class="text-success">#{@best[:length][:lang]}</span>
80 - %br
81 - with <span class="text-success">#{@best[:length][:value]} bytes</span>
82 - %br
83 - at submission
84 - = link_to "#" + @best[:length][:sub_id].to_s, submission_path(@best[:length][:sub_id])
85 -
86 - %tr
87 - %td.info_param First solver
88 - %td
89 - - if @best[:first][:user] != '(NULL)'
90 - #{link_to @best[:first][:user], stat_user_path(@best[:first][:user_id])} is the first solver
91 - %br
92 - using <span class="text-success">#{@best[:first][:lang]}</span>
93 - %br
94 - on <span class="text-success">#{@best[:first][:value]}</span>
95 - %br
96 - at submission
97 - = link_to "#" + @best[:first][:sub_id].to_s, submission_path( @best[:first][:sub_id])
98 - - else
99 - no first solver
100 .col-md-8
64 .col-md-8
101 - if @best
65 - if @best
102 - %h2 By Language
66 + .card
67 + .card-body
68 + %h2.card-title Top Submissions
103 %table.table.table-hover
69 %table.table.table-hover
104 %thead
70 %thead
105 %tr
71 %tr
106 %th Language
72 %th Language
107 %th Best runtime (ms)
73 %th Best runtime (ms)
108 %th Best memory (kbytes)
74 %th Best memory (kbytes)
109 %th Shortest Code (bytes)
75 %th Shortest Code (bytes)
110 %th First solver
76 %th First solver
111 %tbody
77 %tbody
78 + %tr.bg-warning
79 + %td
80 + Overall
81 + %td
82 + by #{link_to @best[:runtime][:user], stat_user_path(@best[:runtime][:user_id])}
83 + %br
84 + using <span class="text-success">#{@best[:runtime][:lang]}</span>
85 + %br
86 + with <span class="text-success">#{@best[:runtime][:value] * 1000} milliseconds</span>
87 + %br= link_to "#" + @best[:runtime][:sub_id].to_s, submission_path(@best[:runtime][:sub_id])
88 + %td
89 + by #{link_to @best[:memory][:user], stat_user_path(@best[:memory][:user_id])}
90 + %br
91 + using <span class="text-success">#{@best[:memory][:lang]}</span>
92 + %br
93 + with <span class="text-success">#{number_with_delimiter(@best[:memory][:value])} kbytes </span>
94 + %br= link_to "#" + @best[:memory][:sub_id].to_s, submission_path(@best[:memory][:sub_id])
95 + %td
96 + by #{link_to @best[:length][:user], stat_user_path(@best[:length][:user_id])}
97 + %br
98 + using <span class="text-success">#{@best[:length][:lang]}</span>
99 + %br
100 + with <span class="text-success">#{@best[:length][:value]} bytes</span>
101 + %br= link_to "#" + @best[:length][:sub_id].to_s, submission_path(@best[:length][:sub_id])
102 + %td
103 + - if @best[:first][:user] != '(NULL)'
104 + #{link_to @best[:first][:user], stat_user_path(@best[:first][:user_id])} is the first solver
105 + %br
106 + using <span class="text-success">#{@best[:first][:lang]}</span>
107 + %br
108 + on <span class="text-success">#{@best[:first][:value]}</span>
109 + %br= link_to "#" + @best[:first][:sub_id].to_s, submission_path( @best[:first][:sub_id])
110 + - else
111 + no first solver
112 - @by_lang.each do |lang,value|
112 - @by_lang.each do |lang,value|
113 %tr
113 %tr
114 %td= lang
114 %td= lang
115 %td
115 %td
116 = link_to value[:runtime][:user], stat_user_path(value[:runtime][:user_id])
116 = link_to value[:runtime][:user], stat_user_path(value[:runtime][:user_id])
117 %br
117 %br
@@ -131,6 +131,24
131 - if value[:first][:user] != '(NULL)' #TODO: i know... this is wrong...
131 - if value[:first][:user] != '(NULL)' #TODO: i know... this is wrong...
132 = link_to value[:first][:user], stat_user_path(value[:first][:user_id])
132 = link_to value[:first][:user], stat_user_path(value[:first][:user_id])
133 %br
133 %br
134 = "#{value[:first][:value]} @"
134 = "#{value[:first][:value]} @"
135 = link_to "#" + value[:first][:sub_id].to_s, submission_path( value[:first][:sub_id])
135 = link_to "#" + value[:first][:sub_id].to_s, submission_path( value[:first][:sub_id])
136
136
137 + %script{src:"https://cdn.jsdelivr.net/npm/chart.js"}
138 + :javascript
139 + data = #{@chart_dataset}
140 + config = {
141 + type: 'bar',
142 + data: data,
143 + options: {
144 + plugins: {
145 + legend: {
146 + display: false
147 + },
148 + },
149 + }
150 + }
151 + Chart.defaults.font.size = 15
152 + //Chart.defaults.font.family = 'Sarabun Light'
153 + chart = new Chart($('#chart'),config)
154 +
@@ -20,10 +20,10
20
20
21 - unless params[:id]
21 - unless params[:id]
22 /=render partial: 'all_time_hof'
22 /=render partial: 'all_time_hof'
23 Please select a problem.
23 Please select a problem.
24 - else
24 - else
25 %h1 [#{Problem.find(params[:id]).name}] #{Problem.find(params[:id]).full_name}
25 %h1 [#{Problem.find(params[:id]).name}] #{Problem.find(params[:id]).full_name}
26 - %h2 Submission History
26 + -# %h2 Submission History
27 - =render partial: 'application/bar_graph', locals: { histogram: @histogram }
27 + -# =render partial: 'application/bar_graph', locals: { histogram: @histogram }
28 =render partial: 'task_hof'
28 =render partial: 'task_hof'
29
29
@@ -86,24 +86,36
86 %tr
86 %tr
87 %td.text-right
87 %td.text-right
88 %strong Compiler result
88 %strong Compiler result
89 %td
89 %td
90 %button.btn.btn-info.btn-xs{type: 'button', data: {toggle: 'modal', target: '#compiler'}}
90 %button.btn.btn-info.btn-xs{type: 'button', data: {toggle: 'modal', target: '#compiler'}}
91 view
91 view
92 + %tr
93 + %td.text-right
94 + %strong Grading Task Status
95 + %td
96 + = @task.status_str if @task
97 + - if session[:admin]
98 + = link_to "rejudge", rejudge_submission_path, data: {remote: true}, class: 'btn btn-info btn-xs'
92 - if session[:admin]
99 - if session[:admin]
93 %tr
100 %tr
94 %td.text-right
101 %td.text-right
95 %strong IP
102 %strong IP
96 %td #{@submission.ip_address}
103 %td #{@submission.ip_address}
97 %tr
104 %tr
98 %td.text-right
105 %td.text-right
99 - %strong Grading Task Status
106 + %strong Model solution
100 %td
107 %td
101 - = @task.status_str if @task
108 + - if @submission.tag_model?
109 + YES
102 - if session[:admin]
110 - if session[:admin]
103 - = link_to "rejudge", rejudge_submission_path, data: {remote: true}, class: 'btn btn-info btn-xs'
111 + = link_to "remove model status", set_tag_submission_path(@submission, tag: :default), class: 'btn btn-warning btn-xs'
112 + - else
113 + No
114 + - if session[:admin]
115 + = link_to "set as model solution", set_tag_submission_path(@submission, tag: :model), class: 'btn btn-success btn-xs'
104
116
105
117
106 .modal.fade#compiler{tabindex: -1,role: 'dialog'}
118 .modal.fade#compiler{tabindex: -1,role: 'dialog'}
107 .modal-dialog.modal-lg{role:'document'}
119 .modal-dialog.modal-lg{role:'document'}
108 .modal-content
120 .modal-content
109 .modal-header
121 .modal-header
@@ -91,12 +91,13
91
91
92 resources :submissions do
92 resources :submissions do
93 member do
93 member do
94 get 'download'
94 get 'download'
95 get 'compiler_msg'
95 get 'compiler_msg'
96 get 'rejudge'
96 get 'rejudge'
97 + get 'set_tag'
97 end
98 end
98 collection do
99 collection do
99 get 'prob/:problem_id', to: 'submissions#index', as: 'problem'
100 get 'prob/:problem_id', to: 'submissions#index', as: 'problem'
100 get 'direct_edit_problem/:problem_id(/:user_id)', to: 'submissions#direct_edit_problem', as: 'direct_edit_problem'
101 get 'direct_edit_problem/:problem_id(/:user_id)', to: 'submissions#direct_edit_problem', as: 'direct_edit_problem'
101 get 'get_latest_submission_status/:uid/:pid', to: 'submissions#get_latest_submission_status', as: 'get_latest_submission_status'
102 get 'get_latest_submission_status/:uid/:pid', to: 'submissions#get_latest_submission_status', as: 'get_latest_submission_status'
102 end
103 end
@@ -1,312 +1,314
1 # This file is auto-generated from the current state of the database. Instead
1 # This file is auto-generated from the current state of the database. Instead
2 # of editing this file, please use the migrations feature of Active Record to
2 # of editing this file, please use the migrations feature of Active Record to
3 # incrementally modify your database, and then regenerate this schema definition.
3 # incrementally modify your database, and then regenerate this schema definition.
4 #
4 #
5 - # Note that this schema.rb definition is the authoritative source for your
5 + # This file is the source Rails uses to define your schema when running `bin/rails
6 - # database schema. If you need to create the application database on another
6 + # db:schema:load`. When creating a new database, `bin/rails db:schema:load` tends to
7 - # system, you should be using db:schema:load, not running all the migrations
7 + # be faster and is potentially less error prone than running all of your
8 - # from scratch. The latter is a flawed and unsustainable approach (the more migrations
8 + # migrations from scratch. Old migrations may fail to apply correctly if those
9 - # you'll amass, the slower it'll run and the greater likelihood for issues).
9 + # migrations use external dependencies or application code.
10 #
10 #
11 # It's strongly recommended that you check this file into your version control system.
11 # It's strongly recommended that you check this file into your version control system.
12
12
13 - ActiveRecord::Schema.define(version: 2021_08_09_105935) do
13 + ActiveRecord::Schema.define(version: 2022_02_04_080936) do
14
14
15 - create_table "announcements", id: :integer, options: "ENGINE=InnoDB DEFAULT CHARSET=utf8", force: :cascade do |t|
15 + create_table "announcements", id: :integer, charset: "utf8", collation: "utf8_unicode_ci", force: :cascade do |t|
16 t.string "author"
16 t.string "author"
17 - t.text "body", limit: 16777215
17 + t.text "body"
18 t.boolean "published"
18 t.boolean "published"
19 t.datetime "created_at", null: false
19 t.datetime "created_at", null: false
20 t.datetime "updated_at", null: false
20 t.datetime "updated_at", null: false
21 t.boolean "frontpage", default: false
21 t.boolean "frontpage", default: false
22 t.boolean "contest_only", default: false
22 t.boolean "contest_only", default: false
23 t.string "title"
23 t.string "title"
24 t.string "notes"
24 t.string "notes"
25 t.boolean "on_nav_bar", default: false
25 t.boolean "on_nav_bar", default: false
26 end
26 end
27
27
28 - create_table "contests", id: :integer, options: "ENGINE=InnoDB DEFAULT CHARSET=utf8", force: :cascade do |t|
28 + create_table "contests", id: :integer, charset: "utf8", collation: "utf8_unicode_ci", force: :cascade do |t|
29 t.string "title"
29 t.string "title"
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"
33 t.string "name"
34 end
34 end
35
35
36 - create_table "contests_problems", id: false, options: "ENGINE=InnoDB DEFAULT CHARSET=utf8", force: :cascade do |t|
36 + create_table "contests_problems", id: false, charset: "utf8", collation: "utf8_unicode_ci", force: :cascade do |t|
37 t.integer "contest_id"
37 t.integer "contest_id"
38 t.integer "problem_id"
38 t.integer "problem_id"
39 end
39 end
40
40
41 - create_table "contests_users", id: false, options: "ENGINE=InnoDB DEFAULT CHARSET=utf8", force: :cascade do |t|
41 + create_table "contests_users", id: false, charset: "utf8", collation: "utf8_unicode_ci", force: :cascade do |t|
42 t.integer "contest_id"
42 t.integer "contest_id"
43 t.integer "user_id"
43 t.integer "user_id"
44 end
44 end
45
45
46 - create_table "countries", id: :integer, options: "ENGINE=InnoDB DEFAULT CHARSET=utf8", force: :cascade do |t|
46 + create_table "countries", id: :integer, charset: "utf8", collation: "utf8_unicode_ci", force: :cascade do |t|
47 t.string "name"
47 t.string "name"
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", id: :integer, options: "ENGINE=InnoDB DEFAULT CHARSET=utf8", force: :cascade do |t|
52 + create_table "descriptions", id: :integer, charset: "utf8", collation: "utf8_unicode_ci", force: :cascade do |t|
53 - t.text "body", limit: 16777215
53 + t.text "body"
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", id: :integer, options: "ENGINE=InnoDB DEFAULT CHARSET=utf8", force: :cascade do |t|
59 + create_table "grader_configurations", id: :integer, charset: "utf8", collation: "utf8_unicode_ci", force: :cascade do |t|
60 t.string "key"
60 t.string "key"
61 t.string "value_type"
61 t.string "value_type"
62 t.string "value"
62 t.string "value"
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"
66 end
66 end
67
67
68 - create_table "grader_processes", id: :integer, options: "ENGINE=InnoDB DEFAULT CHARSET=utf8", force: :cascade do |t|
68 + create_table "grader_processes", id: :integer, charset: "utf8", collation: "utf8_unicode_ci", force: :cascade do |t|
69 t.string "host"
69 t.string "host"
70 t.integer "pid"
70 t.integer "pid"
71 t.string "mode"
71 t.string "mode"
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"
75 t.integer "task_id"
76 t.string "task_type"
76 t.string "task_type"
77 t.boolean "terminated"
77 t.boolean "terminated"
78 t.index ["host", "pid"], name: "index_grader_processes_on_ip_and_pid"
78 t.index ["host", "pid"], name: "index_grader_processes_on_ip_and_pid"
79 end
79 end
80
80
81 - create_table "groups", id: :integer, options: "ENGINE=InnoDB DEFAULT CHARSET=latin1", force: :cascade do |t|
81 + create_table "groups", id: :integer, charset: "latin1", force: :cascade do |t|
82 t.string "name"
82 t.string "name"
83 t.string "description"
83 t.string "description"
84 t.boolean "enabled", default: true
84 t.boolean "enabled", default: true
85 end
85 end
86
86
87 - create_table "groups_problems", id: false, options: "ENGINE=InnoDB DEFAULT CHARSET=latin1", force: :cascade do |t|
87 + create_table "groups_problems", id: false, charset: "latin1", force: :cascade do |t|
88 t.integer "problem_id", null: false
88 t.integer "problem_id", null: false
89 t.integer "group_id", null: false
89 t.integer "group_id", null: false
90 t.index ["group_id", "problem_id"], name: "index_groups_problems_on_group_id_and_problem_id"
90 t.index ["group_id", "problem_id"], name: "index_groups_problems_on_group_id_and_problem_id"
91 end
91 end
92
92
93 - create_table "groups_users", options: "ENGINE=InnoDB DEFAULT CHARSET=latin1", force: :cascade do |t|
93 + create_table "groups_users", charset: "latin1", force: :cascade do |t|
94 t.integer "group_id", null: false
94 t.integer "group_id", null: false
95 t.integer "user_id", null: false
95 t.integer "user_id", null: false
96 t.index ["user_id", "group_id"], name: "index_groups_users_on_user_id_and_group_id"
96 t.index ["user_id", "group_id"], name: "index_groups_users_on_user_id_and_group_id"
97 end
97 end
98
98
99 - create_table "heart_beats", id: :integer, options: "ENGINE=InnoDB DEFAULT CHARSET=latin1", force: :cascade do |t|
99 + create_table "heart_beats", id: :integer, charset: "utf8", collation: "utf8_unicode_ci", force: :cascade do |t|
100 t.integer "user_id"
100 t.integer "user_id"
101 t.string "ip_address"
101 t.string "ip_address"
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 t.string "status"
104 t.string "status"
105 t.index ["updated_at"], name: "index_heart_beats_on_updated_at"
105 t.index ["updated_at"], name: "index_heart_beats_on_updated_at"
106 end
106 end
107
107
108 - create_table "languages", id: :integer, options: "ENGINE=InnoDB DEFAULT CHARSET=utf8", force: :cascade do |t|
108 + create_table "languages", id: :integer, charset: "utf8", collation: "utf8_unicode_ci", force: :cascade do |t|
109 t.string "name", limit: 10
109 t.string "name", limit: 10
110 t.string "pretty_name"
110 t.string "pretty_name"
111 t.string "ext", limit: 10
111 t.string "ext", limit: 10
112 t.string "common_ext"
112 t.string "common_ext"
113 end
113 end
114
114
115 - create_table "logins", id: :integer, options: "ENGINE=InnoDB DEFAULT CHARSET=latin1", force: :cascade do |t|
115 + create_table "logins", id: :integer, charset: "utf8", collation: "utf8_unicode_ci", force: :cascade do |t|
116 t.integer "user_id"
116 t.integer "user_id"
117 t.string "ip_address"
117 t.string "ip_address"
118 t.datetime "created_at", null: false
118 t.datetime "created_at", null: false
119 t.datetime "updated_at", null: false
119 t.datetime "updated_at", null: false
120 t.index ["user_id"], name: "index_logins_on_user_id"
120 t.index ["user_id"], name: "index_logins_on_user_id"
121 end
121 end
122
122
123 - create_table "messages", id: :integer, options: "ENGINE=InnoDB DEFAULT CHARSET=utf8", force: :cascade do |t|
123 + create_table "messages", id: :integer, charset: "utf8", collation: "utf8_unicode_ci", force: :cascade do |t|
124 t.integer "sender_id"
124 t.integer "sender_id"
125 t.integer "receiver_id"
125 t.integer "receiver_id"
126 t.integer "replying_message_id"
126 t.integer "replying_message_id"
127 - t.text "body", limit: 16777215
127 + t.text "body"
128 t.boolean "replied"
128 t.boolean "replied"
129 t.datetime "created_at", null: false
129 t.datetime "created_at", null: false
130 t.datetime "updated_at", null: false
130 t.datetime "updated_at", null: false
131 end
131 end
132
132
133 - create_table "problems", id: :integer, options: "ENGINE=InnoDB DEFAULT CHARSET=utf8", force: :cascade do |t|
133 + create_table "problems", id: :integer, charset: "utf8", collation: "utf8_unicode_ci", force: :cascade do |t|
134 - t.string "name", limit: 100
134 + t.string "name", limit: 30
135 t.string "full_name"
135 t.string "full_name"
136 t.integer "full_score"
136 t.integer "full_score"
137 t.date "date_added"
137 t.date "date_added"
138 t.boolean "available"
138 t.boolean "available"
139 t.string "url"
139 t.string "url"
140 t.integer "description_id"
140 t.integer "description_id"
141 t.boolean "test_allowed"
141 t.boolean "test_allowed"
142 t.boolean "output_only"
142 t.boolean "output_only"
143 t.string "description_filename"
143 t.string "description_filename"
144 t.boolean "view_testcase"
144 t.boolean "view_testcase"
145 + t.integer "difficulty"
145 end
146 end
146
147
147 - create_table "problems_tags", id: :integer, options: "ENGINE=InnoDB DEFAULT CHARSET=latin1", force: :cascade do |t|
148 + create_table "problems_tags", id: :integer, charset: "latin1", force: :cascade do |t|
148 t.integer "problem_id"
149 t.integer "problem_id"
149 t.integer "tag_id"
150 t.integer "tag_id"
150 t.index ["problem_id", "tag_id"], name: "index_problems_tags_on_problem_id_and_tag_id", unique: true
151 t.index ["problem_id", "tag_id"], name: "index_problems_tags_on_problem_id_and_tag_id", unique: true
151 t.index ["problem_id"], name: "index_problems_tags_on_problem_id"
152 t.index ["problem_id"], name: "index_problems_tags_on_problem_id"
152 t.index ["tag_id"], name: "index_problems_tags_on_tag_id"
153 t.index ["tag_id"], name: "index_problems_tags_on_tag_id"
153 end
154 end
154
155
155 - create_table "rights", id: :integer, options: "ENGINE=InnoDB DEFAULT CHARSET=utf8", force: :cascade do |t|
156 + create_table "rights", id: :integer, charset: "utf8", collation: "utf8_unicode_ci", force: :cascade do |t|
156 t.string "name"
157 t.string "name"
157 t.string "controller"
158 t.string "controller"
158 t.string "action"
159 t.string "action"
159 end
160 end
160
161
161 - create_table "rights_roles", id: false, options: "ENGINE=InnoDB DEFAULT CHARSET=utf8", force: :cascade do |t|
162 + create_table "rights_roles", id: false, charset: "utf8", collation: "utf8_unicode_ci", force: :cascade do |t|
162 t.integer "right_id"
163 t.integer "right_id"
163 t.integer "role_id"
164 t.integer "role_id"
164 t.index ["role_id"], name: "index_rights_roles_on_role_id"
165 t.index ["role_id"], name: "index_rights_roles_on_role_id"
165 end
166 end
166
167
167 - create_table "roles", id: :integer, options: "ENGINE=InnoDB DEFAULT CHARSET=utf8", force: :cascade do |t|
168 + create_table "roles", id: :integer, charset: "utf8", collation: "utf8_unicode_ci", force: :cascade do |t|
168 t.string "name"
169 t.string "name"
169 end
170 end
170
171
171 - create_table "roles_users", id: false, options: "ENGINE=InnoDB DEFAULT CHARSET=utf8", force: :cascade do |t|
172 + create_table "roles_users", id: false, charset: "utf8", collation: "utf8_unicode_ci", force: :cascade do |t|
172 t.integer "role_id"
173 t.integer "role_id"
173 t.integer "user_id"
174 t.integer "user_id"
174 t.index ["user_id"], name: "index_roles_users_on_user_id"
175 t.index ["user_id"], name: "index_roles_users_on_user_id"
175 end
176 end
176
177
177 - create_table "sessions", id: :integer, options: "ENGINE=InnoDB DEFAULT CHARSET=utf8", force: :cascade do |t|
178 + create_table "sessions", id: :integer, charset: "utf8", collation: "utf8_unicode_ci", force: :cascade do |t|
178 t.string "session_id"
179 t.string "session_id"
179 - t.text "data", limit: 16777215
180 + t.text "data"
180 t.datetime "updated_at"
181 t.datetime "updated_at"
181 t.index ["session_id"], name: "index_sessions_on_session_id"
182 t.index ["session_id"], name: "index_sessions_on_session_id"
182 t.index ["updated_at"], name: "index_sessions_on_updated_at"
183 t.index ["updated_at"], name: "index_sessions_on_updated_at"
183 end
184 end
184
185
185 - create_table "sites", id: :integer, options: "ENGINE=InnoDB DEFAULT CHARSET=utf8", force: :cascade do |t|
186 + create_table "sites", id: :integer, charset: "utf8", collation: "utf8_unicode_ci", force: :cascade do |t|
186 t.string "name"
187 t.string "name"
187 t.boolean "started"
188 t.boolean "started"
188 t.datetime "start_time"
189 t.datetime "start_time"
189 t.datetime "created_at", null: false
190 t.datetime "created_at", null: false
190 t.datetime "updated_at", null: false
191 t.datetime "updated_at", null: false
191 t.integer "country_id"
192 t.integer "country_id"
192 t.string "password"
193 t.string "password"
193 end
194 end
194
195
195 - create_table "submission_view_logs", id: :integer, options: "ENGINE=InnoDB DEFAULT CHARSET=latin1", force: :cascade do |t|
196 + create_table "submission_view_logs", id: :integer, charset: "utf8", collation: "utf8_unicode_ci", force: :cascade do |t|
196 t.integer "user_id"
197 t.integer "user_id"
197 t.integer "submission_id"
198 t.integer "submission_id"
198 t.datetime "created_at", null: false
199 t.datetime "created_at", null: false
199 t.datetime "updated_at", null: false
200 t.datetime "updated_at", null: false
200 end
201 end
201
202
202 - create_table "submissions", id: :integer, options: "ENGINE=InnoDB DEFAULT CHARSET=utf8", force: :cascade do |t|
203 + create_table "submissions", id: :integer, charset: "utf8", collation: "utf8_unicode_ci", force: :cascade do |t|
203 t.integer "user_id"
204 t.integer "user_id"
204 t.integer "problem_id"
205 t.integer "problem_id"
205 t.integer "language_id"
206 t.integer "language_id"
206 - t.text "source", limit: 16777215
207 + t.text "source", size: :medium
207 t.binary "binary"
208 t.binary "binary"
208 t.datetime "submitted_at"
209 t.datetime "submitted_at"
209 t.datetime "compiled_at"
210 t.datetime "compiled_at"
210 - t.text "compiler_message", limit: 16777215
211 + t.text "compiler_message"
211 t.datetime "graded_at"
212 t.datetime "graded_at"
212 t.integer "points"
213 t.integer "points"
213 - t.text "grader_comment", limit: 16777215
214 + t.text "grader_comment"
214 t.integer "number"
215 t.integer "number"
215 t.string "source_filename"
216 t.string "source_filename"
216 t.float "max_runtime"
217 t.float "max_runtime"
217 t.integer "peak_memory"
218 t.integer "peak_memory"
218 t.integer "effective_code_length"
219 t.integer "effective_code_length"
219 t.string "ip_address"
220 t.string "ip_address"
221 + t.integer "tag", default: 0
220 t.index ["submitted_at"], name: "index_submissions_on_submitted_at"
222 t.index ["submitted_at"], name: "index_submissions_on_submitted_at"
221 t.index ["user_id", "problem_id", "number"], name: "index_submissions_on_user_id_and_problem_id_and_number", unique: true
223 t.index ["user_id", "problem_id", "number"], name: "index_submissions_on_user_id_and_problem_id_and_number", unique: true
222 t.index ["user_id", "problem_id"], name: "index_submissions_on_user_id_and_problem_id"
224 t.index ["user_id", "problem_id"], name: "index_submissions_on_user_id_and_problem_id"
223 end
225 end
224
226
225 - create_table "tags", id: :integer, options: "ENGINE=InnoDB DEFAULT CHARSET=latin1", force: :cascade do |t|
227 + create_table "tags", id: :integer, charset: "latin1", force: :cascade do |t|
226 t.string "name", null: false
228 t.string "name", null: false
227 t.text "description"
229 t.text "description"
228 t.boolean "public"
230 t.boolean "public"
229 t.datetime "created_at", null: false
231 t.datetime "created_at", null: false
230 t.datetime "updated_at", null: false
232 t.datetime "updated_at", null: false
231 end
233 end
232
234
233 - create_table "tasks", id: :integer, options: "ENGINE=InnoDB DEFAULT CHARSET=utf8", force: :cascade do |t|
235 + create_table "tasks", id: :integer, charset: "utf8", collation: "utf8_unicode_ci", force: :cascade do |t|
234 t.integer "submission_id"
236 t.integer "submission_id"
235 t.datetime "created_at"
237 t.datetime "created_at"
236 t.integer "status"
238 t.integer "status"
237 t.datetime "updated_at"
239 t.datetime "updated_at"
238 t.index ["status"], name: "index_tasks_on_status"
240 t.index ["status"], name: "index_tasks_on_status"
239 t.index ["submission_id"], name: "index_tasks_on_submission_id"
241 t.index ["submission_id"], name: "index_tasks_on_submission_id"
240 end
242 end
241
243
242 - create_table "test_pairs", id: :integer, options: "ENGINE=InnoDB DEFAULT CHARSET=utf8", force: :cascade do |t|
244 + create_table "test_pairs", id: :integer, charset: "utf8", collation: "utf8_unicode_ci", force: :cascade do |t|
243 t.integer "problem_id"
245 t.integer "problem_id"
244 - t.text "input", limit: 4294967295
246 + t.text "input", size: :medium
245 - t.text "solution", limit: 4294967295
247 + t.text "solution", size: :medium
246 t.datetime "created_at", null: false
248 t.datetime "created_at", null: false
247 t.datetime "updated_at", null: false
249 t.datetime "updated_at", null: false
248 end
250 end
249
251
250 - create_table "test_requests", id: :integer, options: "ENGINE=InnoDB DEFAULT CHARSET=utf8", force: :cascade do |t|
252 + create_table "test_requests", id: :integer, charset: "utf8", collation: "utf8_unicode_ci", force: :cascade do |t|
251 t.integer "user_id"
253 t.integer "user_id"
252 t.integer "problem_id"
254 t.integer "problem_id"
253 t.integer "submission_id"
255 t.integer "submission_id"
254 t.string "input_file_name"
256 t.string "input_file_name"
255 t.string "output_file_name"
257 t.string "output_file_name"
256 t.string "running_stat"
258 t.string "running_stat"
257 t.integer "status"
259 t.integer "status"
258 t.datetime "updated_at", null: false
260 t.datetime "updated_at", null: false
259 t.datetime "submitted_at"
261 t.datetime "submitted_at"
260 t.datetime "compiled_at"
262 t.datetime "compiled_at"
261 - t.text "compiler_message", limit: 16777215
263 + t.text "compiler_message"
262 t.datetime "graded_at"
264 t.datetime "graded_at"
263 t.string "grader_comment"
265 t.string "grader_comment"
264 t.datetime "created_at", null: false
266 t.datetime "created_at", null: false
265 t.float "running_time"
267 t.float "running_time"
266 t.string "exit_status"
268 t.string "exit_status"
267 t.integer "memory_usage"
269 t.integer "memory_usage"
268 t.index ["user_id", "problem_id"], name: "index_test_requests_on_user_id_and_problem_id"
270 t.index ["user_id", "problem_id"], name: "index_test_requests_on_user_id_and_problem_id"
269 end
271 end
270
272
271 - create_table "testcases", id: :integer, options: "ENGINE=InnoDB DEFAULT CHARSET=latin1", force: :cascade do |t|
273 + create_table "testcases", id: :integer, charset: "latin1", force: :cascade do |t|
272 t.integer "problem_id"
274 t.integer "problem_id"
273 t.integer "num"
275 t.integer "num"
274 t.integer "group"
276 t.integer "group"
275 t.integer "score"
277 t.integer "score"
276 - t.text "input", limit: 4294967295
278 + t.text "input", size: :long
277 - t.text "sol", limit: 4294967295
279 + t.text "sol", size: :long
278 - t.datetime "created_at", null: false
280 + t.datetime "created_at"
279 - t.datetime "updated_at", null: false
281 + t.datetime "updated_at"
280 t.index ["problem_id"], name: "index_testcases_on_problem_id"
282 t.index ["problem_id"], name: "index_testcases_on_problem_id"
281 end
283 end
282
284
283 - create_table "user_contest_stats", id: :integer, options: "ENGINE=InnoDB DEFAULT CHARSET=utf8", force: :cascade do |t|
285 + create_table "user_contest_stats", id: :integer, charset: "utf8", collation: "utf8_unicode_ci", force: :cascade do |t|
284 t.integer "user_id"
286 t.integer "user_id"
285 t.datetime "started_at"
287 t.datetime "started_at"
286 t.datetime "created_at", null: false
288 t.datetime "created_at", null: false
287 t.datetime "updated_at", null: false
289 t.datetime "updated_at", null: false
288 t.boolean "forced_logout"
290 t.boolean "forced_logout"
289 end
291 end
290
292
291 - create_table "users", id: :integer, options: "ENGINE=InnoDB DEFAULT CHARSET=utf8", force: :cascade do |t|
293 + create_table "users", id: :integer, charset: "utf8", collation: "utf8_unicode_ci", force: :cascade do |t|
292 t.string "login", limit: 50
294 t.string "login", limit: 50
293 t.string "full_name"
295 t.string "full_name"
294 t.string "hashed_password"
296 t.string "hashed_password"
295 t.string "salt", limit: 5
297 t.string "salt", limit: 5
296 t.string "alias"
298 t.string "alias"
297 t.string "email"
299 t.string "email"
298 t.integer "site_id"
300 t.integer "site_id"
299 t.integer "country_id"
301 t.integer "country_id"
300 t.boolean "activated", default: false
302 t.boolean "activated", default: false
301 t.datetime "created_at"
303 t.datetime "created_at"
302 t.datetime "updated_at"
304 t.datetime "updated_at"
303 - t.string "section"
304 t.boolean "enabled", default: true
305 t.boolean "enabled", default: true
305 t.string "remark"
306 t.string "remark"
306 t.string "last_ip"
307 t.string "last_ip"
308 + t.string "section"
307 t.integer "default_language"
309 t.integer "default_language"
308 t.index ["login"], name: "index_users_on_login", unique: true
310 t.index ["login"], name: "index_users_on_login", unique: true
309 end
311 end
310
312
311 add_foreign_key "problems_tags", "problems"
313 add_foreign_key "problems_tags", "problems"
312 add_foreign_key "problems_tags", "tags"
314 add_foreign_key "problems_tags", "tags"
You need to be logged in to leave comments. Login now