Description:
update master
Commit status:
[Not Reviewed]
References:
merge default
Comments:
0 Commit comments 0 Inline Comments
Unresolved TODOs:
There are no unresolved TODOs
Add another comment

r661:50e8e6077bb9 - - 146 files changed: 1434 inserted, 2343 deleted

@@ -0,0 +1,32
1 + class TestcasesController < ApplicationController
2 + before_action :set_testcase, only: [:download_input,:download_sol]
3 + before_action :testcase_authorization
4 +
5 + def download_input
6 + send_data @testcase.input, type: 'text/plain', filename: "#{@testcase.problem.name}.#{@testcase.num}.in"
7 + end
8 +
9 + def download_sol
10 + send_data @testcase.sol, type: 'text/plain', filename: "#{@testcase.problem.name}.#{@testcase.num}.sol"
11 + end
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 +
21 +
22 + private
23 + # Use callbacks to share common setup or constraints between actions.
24 + def set_testcase
25 + @testcase = Testcase.find(params[:id])
26 + end
27 +
28 + # Only allow a trusted parameter "white list" through.
29 + def testcase_params
30 + params[:testcase]
31 + end
32 + end
@@ -0,0 +1,2
1 + module TestcasesHelper
2 + end
@@ -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,4
1 + :plain
2 + $("#compiler_msg").html("#{j @submission.compiler_message}");
3 + $("#compiler").modal();
4 +
@@ -0,0 +1,2
1 + :plain
2 + $("body").prepend("<div class=\"alert alert-info\"> Submission #{@submission.id}'s task status has been changed to \"#{@task.status_str}\". It will be re-judged soon. </div>")
@@ -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,77
1 + %h1 Bulk Manage User
2 +
3 + = form_tag bulk_manage_user_admin_path
4 + .row
5 + .col-md-6
6 + .panel.panel-primary
7 + .panel-title.panel-heading
8 + Filter User
9 + .panel-body
10 + Filtering users whose login match the following MySQL regex
11 + .form-group
12 + = label_tag "regex", 'Regex Pattern'
13 + = text_field_tag "regex", params[:regex], class: 'form-control'
14 + %p
15 + Example
16 + %ul
17 + %li
18 + %code root
19 + matches every user whose login contains "root"
20 + %li
21 + %code ^56
22 + matches every user whose login starts with "56"
23 + %li
24 + %code 21$
25 + matches every user whose login ends with "21"
26 + .col-md-6
27 + .panel.panel-primary
28 + .panel-title.panel-heading
29 + Action
30 + .panel-body
31 + .row.form-group
32 + .col-md-6
33 + %label.checkbox-inline
34 + = check_box_tag "enabled", true, params[:enabled]
35 + Change "Enabled" to
36 + .col-md-3
37 + %label.radio-inline
38 + = radio_button_tag "enable", 1, params[:enable] == '1', id: 'enable-yes'
39 + Yes
40 + .col-md-3
41 + %label.radio-inline
42 + = radio_button_tag "enable", 0, params[:enable] == '0', id: 'enable-no'
43 + No
44 + .row.form-group
45 + .col-md-6
46 + %label.checkbox-inline
47 + = check_box_tag "gen_password", true, params[:gen_password]
48 + Generate new random password
49 +
50 + .row
51 + .col-md-12
52 + = submit_tag "Preview Result", class: 'btn btn-default'
53 + - if @users
54 + .row
55 + .col-md-4
56 + - if @action
57 + %h2 Confirmation
58 + - if @action[:set_enable]
59 + .alert.alert-info The following users will be set #{(@action[:enabled] ? 'enable' : 'disable')}.
60 + - if @action[:gen_password]
61 + .alert.alert-info The password of the following users will be randomly generated.
62 + .row
63 + .col-md-4
64 + = submit_tag "Perform", class: 'btn btn-primary'
65 + .row
66 + .col-md-12
67 + The pattern matches #{@users.count} following users.
68 + %br
69 + - @users.each do |user|
70 + = user.login
71 + = ' '
72 + = user.full_name
73 + = ' '
74 + = "(#{user.remark})" if user.remark
75 + %br
76 +
77 +
@@ -0,0 +1,8
1 + development:
2 + secret_key_base: '444f426d08add8e2d7cbd76e2057e521e06091231eb4d5472af6ba5654ea1124ce6a636f549be6827ce09561c314181226ad840d44e4677e1077942ee0dc82bd'
3 +
4 + test:
5 + secret_key_base: 'd52f411b06a79cc9f56d92e10d27e670cf0f0c3357e7caf9018ec23091b5c452ea9266c03a5c9e37b72c358702d4d460e957f90dcc553c9fc73a98adb520e781'
6 +
7 + production:
8 + secret_key_base: '7f85485d3d652fc6336dfe3cd98917d9bd7a323b32096bf7635d26b98ccd0480816cc2d12b5c10805cecf7d8fb322104e2bda71eb60dd871c5c537e56a063038'
@@ -0,0 +1,16
1 + class AddConfigViewTest < ActiveRecord::Migration
2 + def up
3 + GraderConfiguration.create key: 'right.view_testcase', value_type: 'boolean', value:'true', description:'When true, any user can view/download test data'
4 + #uglily and dirtily and shamelessly check other config and inifialize
5 + GraderConfiguration.where(key: 'right.user_hall_of_fame').first_or_create(value_type: 'boolean', value: 'false',
6 + description: 'If true, any user can access hall of fame page.')
7 + GraderConfiguration.where(key: 'right.multiple_ip_login').first_or_create(value_type: 'boolean', value: 'false',
8 + description: 'When change from true to false, a user can login from the first IP they logged into afterward.')
9 + GraderConfiguration.where(key: 'right.user_view_submission').first_or_create(value_type: 'boolean', value: 'false',
10 + description: 'If true, any user can view submissions of every one.')
11 + end
12 +
13 + def down
14 + GraderConfiguration.where(key: 'right.view_testcase').destroy_all;
15 + end
16 + end
@@ -0,0 +1,6
1 + class ChangeTestcaseSize < ActiveRecord::Migration
2 + def change
3 + change_column :testcases, :input, :text, :limit => 4294967295
4 + change_column :testcases, :sol, :text, :limit => 4294967295
5 + end
6 + end
@@ -0,0 +1,5
1 + class AddViewTestcaseToProblem < ActiveRecord::Migration
2 + def change
3 + add_column :problems, :view_testcase, :bool
4 + end
5 + end
@@ -0,0 +1,5
1 + class AddIndexToTask < ActiveRecord::Migration
2 + def change
3 + add_index :tasks, :submission_id
4 + end
5 + end
@@ -0,0 +1,9
1 + class AddHeartBeatFull < ActiveRecord::Migration
2 + def up
3 + GraderConfiguration.create key: 'right.heartbeat_response_full', value_type: 'string', value:'RESTART', description:'Heart beat response text when user got full score (set this value to the empty string to disable this feature)'
4 + end
5 +
6 + def down
7 +
8 + end
9 + end
@@ -0,0 +1,41
1 + # Original from http://snippets.dzone.com/posts/show/4468 by MichaelBoutros
2 + #
3 + # Optimized version which uses to_yaml for content creation and checks
4 + # that models are ActiveRecord::Base models before trying to fetch
5 + # them from database.
6 + namespace :db do
7 + namespace :fixtures do
8 + desc 'Dumps all models into fixtures.'
9 + task :dump => :environment do
10 + puts "rails root = #{Rails.root}"
11 + models = Dir.glob(Rails.root.to_s + '/app/models/**.rb').map do |s|
12 + Pathname.new(s).basename.to_s.gsub(/\.rb$/,'').camelize
13 + end
14 +
15 + puts "Found models: " + models.join(', ')
16 +
17 + models.each do |m|
18 + model = m.constantize
19 + next unless model.ancestors.include?(ActiveRecord::Base)
20 +
21 + puts "Dumping model: " + m
22 + entries = model.all.order(id: :asc)
23 +
24 + increment = 1
25 +
26 + model_file = Rails.root.to_s + '/test/fixtures2/' + m.underscore.pluralize + '.yml'
27 + File.open(model_file, 'w') do |f|
28 + entries.each do |a|
29 + attrs = a.attributes
30 + attrs.delete_if{|k,v| v.blank?}
31 +
32 + output = {m + '_' + increment.to_s => attrs}
33 + f << output.to_yaml.gsub(/^--- \n/,'') + "\n"
34 +
35 + increment += 1
36 + end
37 + end
38 + end
39 + end
40 + end
41 + end
@@ -0,0 +1,50
1 + require 'test_helper'
2 +
3 + class AnnouncementsControllerTest < ActionController::TestCase
4 + setup do
5 + @announcement = announcements(:one)
6 + @request.session[:user_id] = users(:admin).id
7 + end
8 +
9 + test "should get index" do
10 + get :index
11 + assert_response :success
12 + assert_not_nil assigns(:announcements)
13 + end
14 +
15 + test "should get new" do
16 + get :new
17 + assert_response :success
18 + end
19 +
20 + test "should create announcement" do
21 + assert_difference('Announcement.count') do
22 + post :create, announcement: { author: 'aa',body: 'bb', published: true, frontpage: true, title: 'test'}
23 + end
24 +
25 + assert_redirected_to announcement_path(assigns(:announcement))
26 + end
27 +
28 + test "should show announcement" do
29 + get :show, id: @announcement
30 + assert_response :success
31 + end
32 +
33 + test "should get edit" do
34 + get :edit, id: @announcement
35 + assert_response :success
36 + end
37 +
38 + test "should update announcement" do
39 + patch :update, id: @announcement, announcement: { author: 'aa',body: 'bb', published: true, frontpage: true, title: 'test'}
40 + assert_redirected_to announcement_path(assigns(:announcement))
41 + end
42 +
43 + test "should destroy announcement" do
44 + assert_difference('Announcement.count', -1) do
45 + delete :destroy, id: @announcement
46 + end
47 +
48 + assert_redirected_to announcements_path
49 + end
50 + end
@@ -0,0 +1,7
1 + require 'test_helper'
2 +
3 + class TestcasesControllerTest < ActionController::TestCase
4 + setup do
5 + @testcase = testcases(:one)
6 + end
7 + end
@@ -0,0 +1,144
1 + GraderConfiguration_1:
2 + key: system.single_user_mode
3 + value_type: boolean
4 + value: 'false'
5 + description: Only admins can log in to the system when running under single user mode.
6 +
7 + GraderConfiguration_2:
8 + key: ui.front.title
9 + value_type: string
10 + value: Grader
11 +
12 + GraderConfiguration_3:
13 + key: ui.front.welcome_message
14 + value_type: string
15 + value: Welcome!
16 +
17 + GraderConfiguration_4:
18 + key: ui.show_score
19 + value_type: boolean
20 + value: 'true'
21 +
22 + GraderConfiguration_5:
23 + key: contest.time_limit
24 + value_type: string
25 + value: unlimited
26 + description: Time limit in format hh:mm, or "unlimited" for contests with no time
27 + limits. This config is CACHED. Restart the server before the change can take
28 + effect.
29 +
30 + GraderConfiguration_6:
31 + key: system.mode
32 + value_type: string
33 + value: standard
34 + description: Current modes are "standard", "contest", "indv-contest", and "analysis".
35 +
36 +
37 + GraderConfiguration_7:
38 + key: contest.name
39 + value_type: string
40 + value: Grader
41 + description: This name will be shown on the user header bar.
42 +
43 +
44 + GraderConfiguration_8:
45 + key: contest.multisites
46 + value_type: boolean
47 + value: 'false'
48 + description: If the server is in contest mode and this option is true, on the log
49 + in of the admin a menu for site selections is shown.
50 +
51 +
52 + GraderConfiguration_9:
53 + key: right.user_hall_of_fame
54 + value_type: boolean
55 + value: 'false'
56 + description: If true, any user can access hall of fame page.
57 +
58 +
59 + GraderConfiguration_10:
60 + key: right.multiple_ip_login
61 + value_type: boolean
62 + value: 'true'
63 + description: When change from true to false, a user can login from the first IP
64 + they logged into afterward.
65 +
66 +
67 + GraderConfiguration_11:
68 + key: right.user_view_submission
69 + value_type: boolean
70 + value: 'false'
71 + description: If true, any user can view submissions of every one.
72 +
73 +
74 + GraderConfiguration_12:
75 + key: right.bypass_agreement
76 + value_type: boolean
77 + value: 'true'
78 + description: When false, a user must accept usage agreement before login
79 +
80 +
81 + GraderConfiguration_13:
82 + key: right.heartbeat_response
83 + value_type: string
84 + value: OK
85 + description: Heart beat response text
86 +
87 +
88 + GraderConfiguration_14:
89 + key: right.view_testcase
90 + value_type: boolean
91 + value: 'false'
92 + description: When true, any user can view/download test data
93 +
94 +
95 + GraderConfiguration_15:
96 + key: system.online_registration.smtp
97 + value_type: string
98 + value: smtp.somehost.com
99 +
100 +
101 + GraderConfiguration_16:
102 + key: system.online_registration.from
103 + value_type: string
104 + value: your.email@address
105 +
106 +
107 + GraderConfiguration_17:
108 + key: system.admin_email
109 + value_type: string
110 + value: admin@admin.email
111 +
112 +
113 + GraderConfiguration_18:
114 + key: system.user_setting_enabled
115 + value_type: boolean
116 + value: 'true'
117 + description: If this option is true, users can change their settings
118 +
119 +
120 + GraderConfiguration_19:
121 + key: contest.test_request.early_timeout
122 + value_type: boolean
123 + value: 'false'
124 +
125 +
126 + GraderConfiguration_20:
127 + key: system.multicontests
128 + value_type: boolean
129 + value: 'false'
130 +
131 +
132 + GraderConfiguration_21:
133 + key: contest.confirm_indv_contest_start
134 + value_type: boolean
135 + value: 'false'
136 +
137 +
138 + GraderConfiguration_22:
139 + key: contest.default_contest_name
140 + value_type: string
141 + value: none
142 + description: New user will be assigned to this contest automatically, if it exists. Set
143 + to 'none' if there is no default contest.
144 +
@@ -0,0 +1,7
1 + require 'test_helper'
2 +
3 + class AdminTaskTest < ActionDispatch::IntegrationTest
4 + # test "the truth" do
5 + # assert true
6 + # end
7 + end
@@ -0,0 +1,40
1 + require 'test_helper'
2 +
3 + class LoginTest < ActionDispatch::IntegrationTest
4 + # test "the truth" do
5 + # assert true
6 + # end
7 +
8 + test "login with invalid information" do
9 + get root_path
10 + assert_response :success
11 + post login_login_path, login: "root", password: "hahaha"
12 + assert_redirected_to root_path
13 + end
14 +
15 + test "normal user login" do
16 + get root_path
17 + assert_response :success
18 + post login_login_path, {login: "john", password: "hello" }
19 + assert_redirected_to main_list_path
20 + end
21 +
22 + test "normal user login in single_user mode" do
23 + GraderConfiguration.find_by(key: GraderConfiguration::SINGLE_USER_KEY).update_attributes(value: 'true')
24 + GraderConfiguration.reload
25 + get root_path
26 + assert_response :success
27 + post login_login_path, {login: "john", password: "hello" }
28 + follow_redirect!
29 + assert_redirected_to root_path
30 + end
31 +
32 + test "root login in in single_user mode" do
33 + GraderConfiguration.find_by(key: GraderConfiguration::SINGLE_USER_KEY).update_attributes(value: 'true')
34 + GraderConfiguration.reload
35 + get root_path
36 + assert_response :success
37 + post login_login_path, {login: "admin", password: "admin" }
38 + assert_redirected_to main_list_path
39 + end
40 + end
@@ -31,3 +31,5
31 31 #ignore rvm setting file
32 32 .ruby-gemset
33 33 .ruby-version
34 +
35 + /config/secrets.yml
@@ -1,27 +1,34
1 1 source 'https://rubygems.org'
2 2
3 - gem 'rails', '~>3.2'
3 + #rails
4 + gem 'rails', '~>4.2.0'
5 + gem 'activerecord-session_store'
4 6
5 - gem 'select2-rails'
6 7
7 8 # Bundle edge Rails instead:
8 9 # gem 'rails', :git => 'git://github.com/rails/rails.git'
9 10
11 + #---------------- database ---------------------
12 + #the database
10 13 gem 'mysql2'
14 + #for testing
15 + gem 'sqlite3'
16 + #for dumping database into yaml
17 + gem 'yaml_db'
11 18
12 19 # Gems used only for assets and not required
13 20 # in production environments by default.
14 - group :assets do
15 - gem 'sass-rails', '~> 3.2.6'
16 - gem 'coffee-rails', '~> 3.2.2'
21 + gem 'sass-rails'
22 + gem 'coffee-rails'
17 23
18 24 # See https://github.com/sstephenson/execjs#readme for more supported runtimes
19 25 # gem 'therubyracer', :platforms => :ruby
20 26
21 27 gem 'uglifier'
22 - end
23 28
24 - gem 'prototype-rails'
29 + gem 'haml'
30 + gem 'haml-rails'
31 + # gem 'prototype-rails'
25 32
26 33 # To use ActiveModel has_secure_password
27 34 # gem 'bcrypt-ruby', '~> 3.0.0'
@@ -44,7 +51,7
44 51
45 52 # jquery addition
46 53 gem 'jquery-rails'
47 - gem 'jquery-ui-sass-rails'
54 + gem 'jquery-ui-rails'
48 55 gem 'jquery-timepicker-addon-rails'
49 56 gem 'jquery-tablesorter'
50 57 gem 'jquery-countdown-rails'
@@ -62,19 +69,23
62 69 gem 'momentjs-rails'
63 70 gem 'rails_bootstrap_sortable'
64 71
72 + #----------- user interface -----------------
73 + #select 2
74 + gem 'select2-rails'
65 75 #ace editor
66 76 gem 'ace-rails-ap'
77 + #paginator
78 + gem 'will_paginate', '~> 3.0.7'
67 79
68 - gem 'haml'
69 - gem 'haml-rails'
70 80 gem 'mail'
71 81 gem 'rdiscount'
72 - gem 'test-unit'
73 - gem 'will_paginate', '~> 3.0.7'
74 82 gem 'dynamic_form'
75 83 gem 'in_place_editing'
76 84 gem 'verification', :git => 'https://github.com/sikachu/verification.git'
77 85
78 - group :test, :development do
79 - gem 'rspec-rails', '~> 2.99.0'
80 - end
86 +
87 + #---------------- testiing -----------------------
88 + gem 'minitest-reporters'
89 +
90 + #---------------- for console --------------------
91 + gem 'fuzzy-string-match'
@@ -1,46 +1,63
1 1 GIT
2 2 remote: https://github.com/sikachu/verification.git
3 - revision: 76eaf51b13276ecae54bd9cd115832595d2ff56d
3 + revision: ff31697b940d7b0e2ec65f08764215c96104e76d
4 4 specs:
5 5 verification (1.0.3)
6 - actionpack (>= 3.0.0, < 5.0)
7 - activesupport (>= 3.0.0, < 5.0)
6 + actionpack (>= 3.0.0, < 5.1)
7 + activesupport (>= 3.0.0, < 5.1)
8 8
9 9 GEM
10 10 remote: https://rubygems.org/
11 11 specs:
12 - ace-rails-ap (4.0.2)
13 - actionmailer (3.2.22.5)
14 - actionpack (= 3.2.22.5)
15 - mail (~> 2.5.4)
16 - actionpack (3.2.22.5)
17 - activemodel (= 3.2.22.5)
18 - activesupport (= 3.2.22.5)
19 - builder (~> 3.0.0)
12 + RubyInline (3.12.4)
13 + ZenTest (~> 4.3)
14 + ZenTest (4.11.1)
15 + ace-rails-ap (4.1.1)
16 + actionmailer (4.2.7.1)
17 + actionpack (= 4.2.7.1)
18 + actionview (= 4.2.7.1)
19 + activejob (= 4.2.7.1)
20 + mail (~> 2.5, >= 2.5.4)
21 + rails-dom-testing (~> 1.0, >= 1.0.5)
22 + actionpack (4.2.7.1)
23 + actionview (= 4.2.7.1)
24 + activesupport (= 4.2.7.1)
25 + rack (~> 1.6)
26 + rack-test (~> 0.6.2)
27 + rails-dom-testing (~> 1.0, >= 1.0.5)
28 + rails-html-sanitizer (~> 1.0, >= 1.0.2)
29 + actionview (4.2.7.1)
30 + activesupport (= 4.2.7.1)
31 + builder (~> 3.1)
20 32 erubis (~> 2.7.0)
21 - journey (~> 1.0.4)
22 - rack (~> 1.4.5)
23 - rack-cache (~> 1.2)
24 - rack-test (~> 0.6.1)
25 - sprockets (~> 2.2.1)
26 - activemodel (3.2.22.5)
27 - activesupport (= 3.2.22.5)
28 - builder (~> 3.0.0)
29 - activerecord (3.2.22.5)
30 - activemodel (= 3.2.22.5)
31 - activesupport (= 3.2.22.5)
32 - arel (~> 3.0.2)
33 - tzinfo (~> 0.3.29)
34 - activeresource (3.2.22.5)
35 - activemodel (= 3.2.22.5)
36 - activesupport (= 3.2.22.5)
37 - activesupport (3.2.22.5)
38 - i18n (~> 0.6, >= 0.6.4)
39 - multi_json (~> 1.0)
40 - arel (3.0.3)
41 - autoprefixer-rails (6.0.3)
33 + rails-dom-testing (~> 1.0, >= 1.0.5)
34 + rails-html-sanitizer (~> 1.0, >= 1.0.2)
35 + activejob (4.2.7.1)
36 + activesupport (= 4.2.7.1)
37 + globalid (>= 0.3.0)
38 + activemodel (4.2.7.1)
39 + activesupport (= 4.2.7.1)
40 + builder (~> 3.1)
41 + activerecord (4.2.7.1)
42 + activemodel (= 4.2.7.1)
43 + activesupport (= 4.2.7.1)
44 + arel (~> 6.0)
45 + activerecord-session_store (1.0.0)
46 + actionpack (>= 4.0, < 5.1)
47 + activerecord (>= 4.0, < 5.1)
48 + multi_json (~> 1.11, >= 1.11.2)
49 + rack (>= 1.5.2, < 3)
50 + railties (>= 4.0, < 5.1)
51 + activesupport (4.2.7.1)
52 + i18n (~> 0.7)
53 + json (~> 1.7, >= 1.7.7)
54 + minitest (~> 5.1)
55 + thread_safe (~> 0.3, >= 0.3.4)
56 + tzinfo (~> 1.1)
57 + ansi (1.5.0)
58 + arel (6.0.4)
59 + autoprefixer-rails (6.6.0)
42 60 execjs
43 - json
44 61 best_in_place (3.0.3)
45 62 actionpack (>= 3.2)
46 63 railties (>= 3.2)
@@ -48,138 +65,148
48 65 sass (~> 3.2)
49 66 bootstrap-switch-rails (3.3.3)
50 67 bootstrap-toggle-rails (2.2.1.0)
51 - builder (3.0.4)
52 - coffee-rails (3.2.2)
68 + builder (3.2.2)
69 + coffee-rails (4.2.1)
53 70 coffee-script (>= 2.2.0)
54 - railties (~> 3.2.0)
55 - coffee-script (2.3.0)
71 + railties (>= 4.0.0, < 5.2.x)
72 + coffee-script (2.4.1)
56 73 coffee-script-source
57 74 execjs
58 - coffee-script-source (1.9.0)
59 - diff-lcs (1.2.5)
75 + coffee-script-source (1.12.2)
76 + concurrent-ruby (1.0.4)
60 77 dynamic_form (1.1.4)
61 78 erubis (2.7.0)
62 - execjs (2.3.0)
63 - haml (4.0.6)
79 + execjs (2.7.0)
80 + fuzzy-string-match (1.0.0)
81 + RubyInline (>= 3.8.6)
82 + globalid (0.3.7)
83 + activesupport (>= 4.1.0)
84 + haml (4.0.7)
64 85 tilt
65 - haml-rails (0.4)
66 - actionpack (>= 3.1, < 4.1)
67 - activesupport (>= 3.1, < 4.1)
68 - haml (>= 3.1, < 4.1)
69 - railties (>= 3.1, < 4.1)
70 - hike (1.2.3)
86 + haml-rails (0.9.0)
87 + actionpack (>= 4.0.1)
88 + activesupport (>= 4.0.1)
89 + haml (>= 4.0.6, < 5.0)
90 + html2haml (>= 1.0.1)
91 + railties (>= 4.0.1)
92 + html2haml (2.0.0)
93 + erubis (~> 2.7.0)
94 + haml (~> 4.0.0)
95 + nokogiri (~> 1.6.0)
96 + ruby_parser (~> 3.5)
71 97 i18n (0.7.0)
72 98 in_place_editing (1.2.0)
73 - journey (1.0.4)
74 99 jquery-countdown-rails (2.0.2)
75 - jquery-rails (3.1.2)
76 - railties (>= 3.0, < 5.0)
100 + jquery-rails (4.2.1)
101 + rails-dom-testing (>= 1, < 3)
102 + railties (>= 4.2.0)
77 103 thor (>= 0.14, < 2.0)
78 - jquery-tablesorter (1.13.4)
79 - railties (>= 3.1, < 5)
104 + jquery-tablesorter (1.23.3)
105 + railties (>= 3.2, < 6)
80 106 jquery-timepicker-addon-rails (1.4.1)
81 107 railties (>= 3.1)
82 - jquery-ui-rails (4.0.3)
83 - jquery-rails
84 - railties (>= 3.1.0)
85 - jquery-ui-sass-rails (4.0.3.0)
86 - jquery-rails
87 - jquery-ui-rails (= 4.0.3)
88 - railties (>= 3.1.0)
108 + jquery-ui-rails (6.0.1)
109 + railties (>= 3.2.16)
89 110 json (1.8.3)
90 - mail (2.5.4)
91 - mime-types (~> 1.16)
92 - treetop (~> 1.4.8)
93 - mime-types (1.25.1)
94 - momentjs-rails (2.11.1)
111 + loofah (2.0.3)
112 + nokogiri (>= 1.5.9)
113 + mail (2.6.4)
114 + mime-types (>= 1.16, < 4)
115 + mime-types (3.1)
116 + mime-types-data (~> 3.2015)
117 + mime-types-data (3.2016.0521)
118 + mini_portile2 (2.1.0)
119 + minitest (5.10.1)
120 + minitest-reporters (1.1.13)
121 + ansi
122 + builder
123 + minitest (>= 5.0)
124 + ruby-progressbar
125 + momentjs-rails (2.15.1)
95 126 railties (>= 3.1)
96 127 multi_json (1.12.1)
97 - mysql2 (0.3.20)
98 - polyglot (0.3.5)
99 - power_assert (0.2.2)
100 - prototype-rails (3.2.1)
101 - rails (~> 3.2)
102 - rack (1.4.7)
103 - rack-cache (1.6.1)
104 - rack (>= 0.4)
105 - rack-ssl (1.3.4)
106 - rack
128 + mysql2 (0.4.5)
129 + nokogiri (1.6.8.1)
130 + mini_portile2 (~> 2.1.0)
131 + rack (1.6.5)
107 132 rack-test (0.6.3)
108 133 rack (>= 1.0)
109 - rails (3.2.22.5)
110 - actionmailer (= 3.2.22.5)
111 - actionpack (= 3.2.22.5)
112 - activerecord (= 3.2.22.5)
113 - activeresource (= 3.2.22.5)
114 - activesupport (= 3.2.22.5)
115 - bundler (~> 1.0)
116 - railties (= 3.2.22.5)
117 - rails_bootstrap_sortable (2.0.0)
118 - momentjs-rails (~> 2, >= 2.8.3)
119 - railties (3.2.22.5)
120 - actionpack (= 3.2.22.5)
121 - activesupport (= 3.2.22.5)
122 - rack-ssl (~> 1.3.2)
134 + rails (4.2.7.1)
135 + actionmailer (= 4.2.7.1)
136 + actionpack (= 4.2.7.1)
137 + actionview (= 4.2.7.1)
138 + activejob (= 4.2.7.1)
139 + activemodel (= 4.2.7.1)
140 + activerecord (= 4.2.7.1)
141 + activesupport (= 4.2.7.1)
142 + bundler (>= 1.3.0, < 2.0)
143 + railties (= 4.2.7.1)
144 + sprockets-rails
145 + rails-deprecated_sanitizer (1.0.3)
146 + activesupport (>= 4.2.0.alpha)
147 + rails-dom-testing (1.0.8)
148 + activesupport (>= 4.2.0.beta, < 5.0)
149 + nokogiri (~> 1.6)
150 + rails-deprecated_sanitizer (>= 1.0.1)
151 + rails-html-sanitizer (1.0.3)
152 + loofah (~> 2.0)
153 + rails_bootstrap_sortable (2.0.1)
154 + momentjs-rails (>= 2.8.3)
155 + railties (4.2.7.1)
156 + actionpack (= 4.2.7.1)
157 + activesupport (= 4.2.7.1)
123 158 rake (>= 0.8.7)
124 - rdoc (~> 3.4)
125 - thor (>= 0.14.6, < 2.0)
126 - rake (11.2.2)
127 - rdiscount (2.1.8)
128 - rdoc (3.12.2)
129 - json (~> 1.4)
130 - rouge (1.8.0)
131 - rspec-collection_matchers (1.1.2)
132 - rspec-expectations (>= 2.99.0.beta1)
133 - rspec-core (2.99.2)
134 - rspec-expectations (2.99.2)
135 - diff-lcs (>= 1.1.3, < 2.0)
136 - rspec-mocks (2.99.3)
137 - rspec-rails (2.99.0)
138 - actionpack (>= 3.0)
139 - activemodel (>= 3.0)
140 - activesupport (>= 3.0)
141 - railties (>= 3.0)
142 - rspec-collection_matchers
143 - rspec-core (~> 2.99.0)
144 - rspec-expectations (~> 2.99.0)
145 - rspec-mocks (~> 2.99.0)
146 - sass (3.4.11)
147 - sass-rails (3.2.6)
148 - railties (~> 3.2.0)
149 - sass (>= 3.1.10)
150 - tilt (~> 1.3)
151 - select2-rails (4.0.1)
159 + thor (>= 0.18.1, < 2.0)
160 + rake (12.0.0)
161 + rdiscount (2.2.0.1)
162 + rouge (2.0.7)
163 + ruby-progressbar (1.8.1)
164 + ruby_parser (3.8.3)
165 + sexp_processor (~> 4.1)
166 + sass (3.4.23)
167 + sass-rails (5.0.6)
168 + railties (>= 4.0.0, < 6)
169 + sass (~> 3.1)
170 + sprockets (>= 2.8, < 4.0)
171 + sprockets-rails (>= 2.0, < 4.0)
172 + tilt (>= 1.1, < 3)
173 + select2-rails (4.0.3)
152 174 thor (~> 0.14)
153 - sprockets (2.2.3)
154 - hike (~> 1.2)
155 - multi_json (~> 1.0)
156 - rack (~> 1.0)
157 - tilt (~> 1.1, != 1.3.0)
158 - test-unit (3.0.9)
159 - power_assert
160 - thor (0.19.1)
161 - tilt (1.4.1)
162 - treetop (1.4.15)
163 - polyglot
164 - polyglot (>= 0.3.1)
165 - tzinfo (0.3.51)
166 - uglifier (2.7.0)
167 - execjs (>= 0.3.0)
168 - json (>= 1.8.0)
169 - will_paginate (3.0.7)
175 + sexp_processor (4.7.0)
176 + sprockets (3.7.1)
177 + concurrent-ruby (~> 1.0)
178 + rack (> 1, < 3)
179 + sprockets-rails (3.2.0)
180 + actionpack (>= 4.0)
181 + activesupport (>= 4.0)
182 + sprockets (>= 3.0.0)
183 + sqlite3 (1.3.12)
184 + thor (0.19.4)
185 + thread_safe (0.3.5)
186 + tilt (2.0.5)
187 + tzinfo (1.2.2)
188 + thread_safe (~> 0.1)
189 + uglifier (3.0.4)
190 + execjs (>= 0.3.0, < 3)
191 + will_paginate (3.0.12)
192 + yaml_db (0.4.2)
193 + rails (>= 3.0, < 5.1)
194 + rake (>= 0.8.7)
170 195
171 196 PLATFORMS
172 197 ruby
173 198
174 199 DEPENDENCIES
175 200 ace-rails-ap
201 + activerecord-session_store
176 202 autoprefixer-rails
177 203 best_in_place (~> 3.0.1)
178 204 bootstrap-sass (~> 3.2.0)
179 205 bootstrap-switch-rails
180 206 bootstrap-toggle-rails
181 - coffee-rails (~> 3.2.2)
207 + coffee-rails
182 208 dynamic_form
209 + fuzzy-string-match
183 210 haml
184 211 haml-rails
185 212 in_place_editing
@@ -187,22 +214,22
187 214 jquery-rails
188 215 jquery-tablesorter
189 216 jquery-timepicker-addon-rails
190 - jquery-ui-sass-rails
217 + jquery-ui-rails
191 218 mail
219 + minitest-reporters
192 220 momentjs-rails
193 221 mysql2
194 - prototype-rails
195 - rails (~> 3.2)
222 + rails (~> 4.2.0)
196 223 rails_bootstrap_sortable
197 224 rdiscount
198 225 rouge
199 - rspec-rails (~> 2.99.0)
200 - sass-rails (~> 3.2.6)
226 + sass-rails
201 227 select2-rails
202 - test-unit
228 + sqlite3
203 229 uglifier
204 230 verification!
205 231 will_paginate (~> 3.0.7)
232 + yaml_db
206 233
207 234 BUNDLED WITH
208 - 1.12.5
235 + 1.13.6
@@ -12,7 +12,7
12 12 //
13 13 //= require jquery
14 14 //= require jquery_ujs
15 - //= require jquery.ui.all
15 + //= require jquery-ui
16 16 //= require bootstrap-sprockets
17 17 //= require moment
18 18 //= require bootstrap-sortable
@@ -28,9 +28,6
28 28 //= require custom
29 29 //= require jquery.countdown
30 30 //-------------- addition from local_jquery -----------
31 - //= require jquery.ui.datepicker
32 - //= require jquery.ui.slider
33 - //= require jquery-ui-timepicker-addon
34 31 //= require jquery-tablesorter
35 32 //= require best_in_place
36 33 //= require best_in_place.jquery-ui
@@ -1,13 +1,3
1 - //= require jquery
2 - //= require jquery_ujs
3 - //= require jquery.ui.all
4 - //= require jquery.ui.datepicker
5 - //= require jquery.ui.slider
6 - //= require jquery-ui-timepicker-addon
7 - //= require jquery-tablesorter
8 - //= require best_in_place
9 - //= require best_in_place.jquery-ui
10 -
11 1 $(document).ready(function() {
12 2 /* Activating Best In Place */
13 3 jQuery(".best_in_place").best_in_place();
@@ -14,11 +14,11
14 14 * # *= require_self
15 15 */
16 16
17 - @import "jquery.ui.all";
18 - @import "jquery.ui.core";
19 - @import "jquery.ui.theme";
20 - @import "jquery.ui.datepicker";
21 - @import "jquery.ui.slider";
17 + @import "jquery-ui";
18 + //@import "jquery.ui.core";
19 + //@import "jquery.ui.theme";
20 + //@import "jquery.ui.datepicker";
21 + //@import "jquery.ui.slider";
22 22 @import "jquery-ui-timepicker-addon";
23 23 @import "jquery-tablesorter/theme.metro-dark";
24 24 @import "jquery.countdown";
@@ -7,8 +7,7
7 7 # GET /announcements
8 8 # GET /announcements.xml
9 9 def index
10 - @announcements = Announcement.find(:all,
11 - :order => "created_at DESC")
10 + @announcements = Announcement.order(created_at: :desc)
12 11
13 12 respond_to do |format|
14 13 format.html # index.html.erb
@@ -46,7 +45,7
46 45 # POST /announcements
47 46 # POST /announcements.xml
48 47 def create
49 - @announcement = Announcement.new(params[:announcement])
48 + @announcement = Announcement.new(announcement_params)
50 49
51 50 respond_to do |format|
52 51 if @announcement.save
@@ -66,7 +65,7
66 65 @announcement = Announcement.find(params[:id])
67 66
68 67 respond_to do |format|
69 - if @announcement.update_attributes(params[:announcement])
68 + if @announcement.update_attributes(announcement_params)
70 69 flash[:notice] = 'Announcement was successfully updated.'
71 70 format.html { redirect_to(@announcement) }
72 71 format.js {}
@@ -108,4 +107,10
108 107 format.xml { head :ok }
109 108 end
110 109 end
110 +
111 + private
112 +
113 + def announcement_params
114 + params.require(:announcement).permit(:author, :body, :published, :frontpage, :contest_only, :title)
111 115 end
116 + end
@@ -20,7 +20,7
20 20
21 21 def admin_authorization
22 22 return false unless authenticate
23 - user = User.find(session[:user_id], :include => ['roles'])
23 + user = User.includes(:roles).find(session[:user_id])
24 24 unless user.admin?
25 25 unauthorized_redirect
26 26 return false
@@ -37,6 +37,18
37 37 end
38 38 end
39 39
40 + def testcase_authorization
41 + #admin always has privileged
42 + puts "haha"
43 + if @current_user.admin?
44 + return true
45 + end
46 +
47 + puts "hehe"
48 + puts GraderConfiguration["right.view_testcase"]
49 + unauthorized_redirect unless GraderConfiguration["right.view_testcase"]
50 + end
51 +
40 52 protected
41 53
42 54 def authenticate
@@ -5,8 +5,8
5 5
6 6
7 7 def index
8 - @configurations = GraderConfiguration.find(:all,
9 - :order => '`key`')
8 + @configurations = GraderConfiguration.order(:key)
9 + @group = GraderConfiguration.pluck("grader_configurations.key").map{ |x| x[0...(x.index('.'))] }.uniq.sort
10 10 end
11 11
12 12 def reload
@@ -18,7 +18,7
18 18 @config = GraderConfiguration.find(params[:id])
19 19 User.clear_last_login if @config.key == GraderConfiguration::MULTIPLE_IP_LOGIN_KEY and @config.value == 'true' and params[:grader_configuration][:value] == 'false'
20 20 respond_to do |format|
21 - if @config.update_attributes(params[:grader_configuration])
21 + if @config.update_attributes(configuration_params)
22 22 format.json { head :ok }
23 23 else
24 24 format.json { respond_with_bip(@config) }
@@ -26,4 +26,9
26 26 end
27 27 end
28 28
29 + private
30 + def configuration_params
31 + params.require(:grader_configuration).permit(:key,:value_type,:value,:description)
29 32 end
33 +
34 + end
@@ -11,9 +11,9
11 11 redirect_to :action => 'index' and return
12 12 end
13 13
14 - @users = User.find(:all)
14 + @users = User.all
15 15 @start_times = {}
16 - UserContestStat.find(:all).each do |stat|
16 + UserContestStat.all.each do |stat|
17 17 @start_times[stat.user_id] = stat.started_at
18 18 end
19 19 end
@@ -66,7 +66,7
66 66 @contest = Contest.find(params[:id])
67 67
68 68 respond_to do |format|
69 - if @contest.update_attributes(params[:contest])
69 + if @contest.update_attributes(contests_params)
70 70 flash[:notice] = 'Contest was successfully updated.'
71 71 format.html { redirect_to(@contest) }
72 72 format.xml { head :ok }
@@ -89,4 +89,10
89 89 end
90 90 end
91 91
92 + private
93 +
94 + def contests_params
95 + params.require(:contest).permit(:title,:enabled,:name)
92 96 end
97 +
98 + end
@@ -35,10 +35,8
35 35
36 36 @terminated_processes = GraderProcess.find_terminated_graders
37 37
38 - @last_task = Task.find(:first,
39 - :order => 'created_at DESC')
40 - @last_test_request = TestRequest.find(:first,
41 - :order => 'created_at DESC')
38 + @last_task = Task.last
39 + @last_test_request = TestRequest.last
42 40 @submission = Submission.order("id desc").limit(20)
43 41 @backlog_submission = Submission.where('graded_at is null')
44 42 end
@@ -57,7 +55,7
57 55 end
58 56
59 57 def clear_all
60 - GraderProcess.find(:all).each do |p|
58 + GraderProcess.all.each do |p|
61 59 p.destroy
62 60 end
63 61 redirect_to :action => 'list'
@@ -2,11 +2,11
2 2 before_filter :admin_authorization, :only => ['index']
3 3
4 4 def edit
5 - @user = User.find_by_login(params[:id])
6 - unless @user
7 - render text: "LOGIN_NOT_FOUND"
8 - return
9 - end
5 + #@user = User.find_by_login(params[:id])
6 + #unless @user
7 + # render text: "LOGIN_NOT_FOUND"
8 + # return
9 + #end
10 10
11 11 #hb = HeartBeat.where(user_id: @user.id, ip_address: request.remote_ip).first
12 12 #puts "status = #{params[:status]}"
@@ -19,10 +19,25
19 19 #else
20 20 # HeartBeat.creae(user_id: @user.id, ip_address: request.remote_ip)
21 21 #end
22 - HeartBeat.create(user_id: @user.id, ip_address: request.remote_ip, status: params[:status])
22 + #HeartBeat.create(user_id: @user.id, ip_address: request.remote_ip, status: params[:status])
23 +
24 + res = GraderConfiguration['right.heartbeat_response']
25 + res.strip! if res
26 + full = GraderConfiguration['right.heartbeat_response_full']
27 + full.strip! if full
23 28
29 + if full and full != ''
30 + l = Login.where(ip_address: request.remote_ip).last
31 + @user = l.user
32 + if @user.solve_all_available_problems?
33 + render text: (full || 'OK')
34 + else
35 + render text: (res || 'OK')
36 + end
37 + else
24 38 render text: (GraderConfiguration['right.heartbeat_response'] || 'OK')
25 39 end
40 + end
26 41
27 42 def index
28 43 @hb = HeartBeat.where("updated_at >= ?",Time.zone.now-2.hours).includes(:user).order(:user_id).all
@@ -45,7 +45,7
45 45 # @hidelogin = true
46 46 # end
47 47
48 - @announcements = Announcement.find_for_frontpage
48 + @announcements = Announcement.frontpage
49 49 render :action => 'login', :layout => 'empty'
50 50 end
51 51
@@ -124,23 +124,6
124 124 end
125 125 end
126 126
127 - def submission
128 - @user = User.find(session[:user_id])
129 - @problems = @user.available_problems
130 - if params[:id]==nil
131 - @problem = nil
132 - @submissions = nil
133 - else
134 - @problem = Problem.find_by_id(params[:id])
135 - if (@problem == nil) or (not @problem.available)
136 - redirect_to :action => 'list'
137 - flash[:notice] = 'Error: submissions for that problem are not viewable.'
138 - return
139 - end
140 - @submissions = Submission.find_all_by_user_problem(@user.id, @problem.id)
141 - end
142 - end
143 -
144 127 def result
145 128 if !GraderConfiguration.show_grading_result
146 129 redirect_to :action => 'list' and return
@@ -217,9 +200,9
217 200
218 201 def prepare_announcements(recent=nil)
219 202 if GraderConfiguration.show_tasks_to?(@user)
220 - @announcements = Announcement.find_published(true)
203 + @announcements = Announcement.published(true)
221 204 else
222 - @announcements = Announcement.find_published
205 + @announcements = Announcement.published
223 206 end
224 207 if recent!=nil
225 208 recent_id = recent.to_i
@@ -1,13 +1,14
1 1 class ProblemsController < ApplicationController
2 2
3 - before_filter :authenticate, :authorization
3 + before_action :authenticate, :authorization
4 + before_action :testcase_authorization, only: [:show_testcase]
4 5
5 6 in_place_edit_for :problem, :name
6 7 in_place_edit_for :problem, :full_name
7 8 in_place_edit_for :problem, :full_score
8 9
9 10 def index
10 - @problems = Problem.find(:all, :order => 'date_added DESC')
11 + @problems = Problem.order(date_added: :desc)
11 12 end
12 13
13 14 # GETs should be safe (see http://www.w3.org/2001/tag/doc/whenToUseGet.html)
@@ -27,7 +28,7
27 28 end
28 29
29 30 def create
30 - @problem = Problem.new(params[:problem])
31 + @problem = Problem.new(problem_params)
31 32 @description = Description.new(params[:description])
32 33 if @description.body!=''
33 34 if !@description.save
@@ -46,7 +47,7
46 47 end
47 48
48 49 def quick_create
49 - @problem = Problem.new(params[:problem])
50 + @problem = Problem.new(problem_params)
50 51 @problem.full_name = @problem.name if @problem.full_name == ''
51 52 @problem.full_score = 100
52 53 @problem.available = false
@@ -87,7 +88,7
87 88 flash[:notice] = 'Error: Uploaded file is not PDF'
88 89 render :action => 'edit' and return
89 90 end
90 - if @problem.update_attributes(params[:problem])
91 + if @problem.update_attributes(problem_params)
91 92 flash[:notice] = 'Problem was successfully updated.'
92 93 unless params[:file] == nil or params[:file] == ''
93 94 flash[:notice] = 'Problem was successfully updated and a new PDF file is uploaded.'
@@ -134,9 +135,16
134 135 end
135 136 end
136 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 +
137 146 def turn_all_off
138 - Problem.find(:all,
139 - :conditions => "available = 1").each do |problem|
147 + Problem.available.all.each do |problem|
140 148 problem.available = false
141 149 problem.save
142 150 end
@@ -144,8 +152,7
144 152 end
145 153
146 154 def turn_all_on
147 - Problem.find(:all,
148 - :conditions => "available = 0").each do |problem|
155 + Problem.where.not(available: true).each do |problem|
149 156 problem.available = true
150 157 problem.save
151 158 end
@@ -176,7 +183,7
176 183 end
177 184
178 185 def manage
179 - @problems = Problem.find(:all, :order => 'date_added DESC')
186 + @problems = Problem.order(date_added: :desc)
180 187 end
181 188
182 189 def do_manage
@@ -278,4 +285,10
278 285 def get_problems_stat
279 286 end
280 287
288 + private
289 +
290 + def problem_params
291 + params.require(:problem).permit(:name, :full_name, :full_score, :date_added, :available, :test_allowed,:output_only, :url, :description)
281 292 end
293 +
294 + end
@@ -9,18 +9,14
9 9 before_filter(only: [:problem_hof]) { |c|
10 10 return false unless authenticate
11 11
12 - if GraderConfiguration["right.user_view_submission"]
13 - return true;
14 - end
15 -
16 - admin_authorization
12 + admin_authorization unless GraderConfiguration["right.user_view_submission"]
17 13 }
18 14
19 15 def max_score
20 16 end
21 17
22 18 def current_score
23 - @problems = Problem.find_available_problems
19 + @problems = Problem.available_problems
24 20 @users = User.includes(:contests).includes(:contest_stat).where(enabled: true)
25 21 @scorearray = calculate_max_score(@problems, @users,0,0,true)
26 22
@@ -38,25 +34,27
38 34 #process parameters
39 35 #problems
40 36 @problems = []
37 + if params[:problem_id]
41 38 params[:problem_id].each do |id|
42 39 next unless id.strip != ""
43 40 pid = Problem.find_by_id(id.to_i)
44 41 @problems << pid if pid
45 42 end
43 + end
46 44
47 45 #users
48 46 @users = if params[:user] == "all" then
49 - User.find(:all, :include => [:contests, :contest_stat])
47 + User.includes(:contests).includes(:contest_stat)
50 48 else
51 49 User.includes(:contests).includes(:contest_stat).where(enabled: true)
52 50 end
53 51
54 52 #set up range from param
55 - since_id = params.fetch(:min_id, 0).to_i
56 - until_id = params.fetch(:max_id, 0).to_i
53 + @since_id = params.fetch(:from_id, 0).to_i
54 + @until_id = params.fetch(:to_id, 0).to_i
57 55
58 56 #calculate the routine
59 - @scorearray = calculate_max_score(@problems, @users,since_id,until_id)
57 + @scorearray = calculate_max_score(@problems, @users, @since_id, @until_id)
60 58
61 59 #rencer accordingly
62 60 if params[:button] == 'download' then
@@ -73,9 +71,9
73 71 if params[:commit] == 'download csv'
74 72 @problems = Problem.all
75 73 else
76 - @problems = Problem.find_available_problems
74 + @problems = Problem.available_problems
77 75 end
78 - @users = User.includes(:contests, :contest_stat).where(enabled: true) #find(:all, :include => [:contests, :contest_stat]).where(enabled: true)
76 + @users = User.includes(:contests, :contest_stat).where(enabled: true)
79 77 @scorearray = Array.new
80 78 @users.each do |u|
81 79 ustat = Array.new
@@ -4,7 +4,7
4 4
5 5 def login
6 6 # Site administrator login
7 - @countries = Country.find(:all, :include => :sites)
7 + @countries = Country.includes(:sites).all
8 8 @country_select = @countries.collect { |c| [c.name, c.id] }
9 9
10 10 @country_select_with_all = [['Any',0]]
@@ -59,4 +59,9
59 59 end
60 60 end
61 61
62 + private
63 + def site_params
64 + params.require(:site).permit()
62 65 end
66 +
67 + end
@@ -5,7 +5,7
5 5 # GET /sites
6 6 # GET /sites.xml
7 7 def index
8 - @sites = Site.find(:all, :order => 'country_id')
8 + @sites = Site.order(:country_id)
9 9
10 10 respond_to do |format|
11 11 format.html # index.html.erb
@@ -65,7 +65,7
65 65 @site.clear_start_time_if_not_started
66 66
67 67 respond_to do |format|
68 - if @site.update_attributes(params[:site])
68 + if @site.update_attributes(site_params)
69 69 flash[:notice] = 'Site was successfully updated.'
70 70 format.html { redirect_to(@site) }
71 71 format.xml { head :ok }
@@ -88,4 +88,10
88 88 end
89 89 end
90 90
91 + private
92 +
93 + def site_params
94 + params.require(:site).permit(:name,:started,:start_time,:country_id,:password)
91 95 end
96 +
97 + end
@@ -1,6 +1,7
1 1 class SubmissionsController < ApplicationController
2 - before_filter :authenticate
3 - before_filter :submission_authorization, only: [:show, :direct_edit_submission]
2 + before_action :authenticate
3 + before_action :submission_authorization, only: [:show, :direct_edit_submission, :download, :edit]
4 + before_action :admin_authorization, only: [:rejudge]
4 5
5 6 # GET /submissions
6 7 # GET /submissions.json
@@ -19,7 +20,7
19 20 flash[:notice] = 'Error: submissions for that problem are not viewable.'
20 21 return
21 22 end
22 - @submissions = Submission.find_all_by_user_problem(@user.id, @problem.id)
23 + @submissions = Submission.find_all_by_user_problem(@user.id, @problem.id).order(id: :desc)
23 24 end
24 25 end
25 26
@@ -31,6 +32,20
31 32 #log the viewing
32 33 user = User.find(session[:user_id])
33 34 SubmissionViewLog.create(user_id: session[:user_id],submission_id: @submission.id) unless user.admin?
35 +
36 + @task = @submission.task
37 + end
38 +
39 + def download
40 + @submission = Submission.find(params[:id])
41 + send_data(@submission.source, {:filename => @submission.download_filename, :type => 'text/plain'})
42 + end
43 +
44 + def compiler_msg
45 + @submission = Submission.find(params[:id])
46 + respond_to do |format|
47 + format.js
48 + end
34 49 end
35 50
36 51 #on-site new submission on specific problem
@@ -60,63 +75,18
60 75 end
61 76 end
62 77
63 - # # GET /submissions/new
64 - # # GET /submissions/new.json
65 - # def new
66 - # @submission = Submission.new
67 - #
68 - # respond_to do |format|
69 - # format.html # new.html.erb
70 - # format.json { render json: @submission }
71 - # end
72 - # end
73 - #
74 - #
75 - # # POST /submissions
76 - # # POST /submissions.json
77 - # def create
78 - # @submission = Submission.new(params[:submission])
79 - #
80 - # respond_to do |format|
81 - # if @submission.save
82 - # format.html { redirect_to @submission, notice: 'Submission was successfully created.' }
83 - # format.json { render json: @submission, status: :created, location: @submission }
84 - # else
85 - # format.html { render action: "new" }
86 - # format.json { render json: @submission.errors, status: :unprocessable_entity }
87 - # end
88 - # end
89 - # end
90 - #
91 - # # PUT /submissions/1
92 - # # PUT /submissions/1.json
93 - # def update
94 - # @submission = Submission.find(params[:id])
95 - #
96 - # respond_to do |format|
97 - # if @submission.update_attributes(params[:submission])
98 - # format.html { redirect_to @submission, notice: 'Submission was successfully updated.' }
99 - # format.json { head :no_content }
100 - # else
101 - # format.html { render action: "edit" }
102 - # format.json { render json: @submission.errors, status: :unprocessable_entity }
103 - # end
104 - # end
105 - # end
106 - #
107 - # # DELETE /submissions/1
108 - # # DELETE /submissions/1.json
109 - # def destroy
110 - # @submission = Submission.find(params[:id])
111 - # @submission.destroy
112 - #
113 - # respond_to do |format|
114 - # format.html { redirect_to submissions_url }
115 - # format.json { head :no_content }
116 - # end
117 - # end
78 + # GET /submissions/:id/rejudge
79 + def rejudge
80 + @submission = Submission.find(params[:id])
81 + @task = @submission.task
82 + @task.status_inqueue! if @task
83 + respond_to do |format|
84 + format.js
85 + end
86 + end
118 87
119 88 protected
89 +
120 90 def submission_authorization
121 91 #admin always has privileged
122 92 if @current_user.admin?
@@ -134,4 +104,5
134 104 return false
135 105 end
136 106
107 +
137 108 end
@@ -29,7 +29,7
29 29 end
30 30
31 31 def active
32 - sessions = ActiveRecord::SessionStore::Session.find(:all, :conditions => ["updated_at >= ?", 60.minutes.ago])
32 + sessions = ActiveRecord::SessionStore::Session.where("updated_at >= ?", 60.minutes.ago)
33 33 @users = []
34 34 sessions.each do |session|
35 35 if session.data[:user_id]
@@ -47,7 +47,7
47 47 end
48 48
49 49 def create
50 - @user = User.new(params[:user])
50 + @user = User.new(user_params)
51 51 @user.activated = true
52 52 if @user.save
53 53 flash[:notice] = 'User was successfully created.'
@@ -74,27 +74,39
74 74 if items.length>=2
75 75 login = items[0]
76 76 full_name = items[1]
77 + remark =''
78 + user_alias = ''
77 79
78 80 added_random_password = false
79 - if items.length>=3
81 + if items.length >= 3 and items[2].chomp(" ").length > 0;
80 82 password = items[2].chomp(" ")
81 - user_alias = (items.length>=4) ? items[3] : login
82 83 else
83 84 password = random_password
84 - user_alias = (items.length>=4) ? items[3] : login
85 - added_random_password = true
85 + add_random_password=true;
86 + end
87 +
88 + if items.length>= 4 and items[3].chomp(" ").length > 0;
89 + user_alias = items[3].chomp(" ")
90 + else
91 + user_alias = login
92 + end
93 +
94 + if items.length>=5
95 + remark = items[4].strip;
86 96 end
87 97
88 98 user = User.find_by_login(login)
89 99 if (user)
90 100 user.full_name = full_name
91 101 user.password = password
102 + user.remark = remark
92 103 else
93 104 user = User.new({:login => login,
94 105 :full_name => full_name,
95 106 :password => password,
96 107 :password_confirmation => password,
97 - :alias => user_alias})
108 + :alias => user_alias,
109 + :remark => remark})
98 110 end
99 111 user.activated = true
100 112 user.save
@@ -106,7 +118,7
106 118 end
107 119 end
108 120 end
109 - flash[:notice] = 'User(s) ' + note.join(', ') +
121 + flash[:success] = 'User(s) ' + note.join(', ') +
110 122 ' were successfully created. ' +
111 123 '( (+) - created with random passwords.)'
112 124 redirect_to :action => 'index'
@@ -118,7 +130,7
118 130
119 131 def update
120 132 @user = User.find(params[:id])
121 - if @user.update_attributes(params[:user])
133 + if @user.update_attributes(user_params)
122 134 flash[:notice] = 'User was successfully updated.'
123 135 redirect_to :action => 'show', :id => @user
124 136 else
@@ -135,9 +147,9
135 147 if params[:commit] == 'download csv'
136 148 @problems = Problem.all
137 149 else
138 - @problems = Problem.find_available_problems
150 + @problems = Problem.available_problems
139 151 end
140 - @users = User.includes(:contests, :contest_stat).where(enabled: true) #find(:all, :include => [:contests, :contest_stat]).where(enabled: true)
152 + @users = User.includes(:contests, :contest_stat).where(enabled: true)
141 153 @scorearray = Array.new
142 154 @users.each do |u|
143 155 ustat = Array.new
@@ -164,9 +176,9
164 176 if params[:commit] == 'download csv'
165 177 @problems = Problem.all
166 178 else
167 - @problems = Problem.find_available_problems
179 + @problems = Problem.available_problems
168 180 end
169 - @users = User.find(:all, :include => [:contests, :contest_stat])
181 + @users = User.includes(:contests).includes(:contest_stat).all
170 182 @scorearray = Array.new
171 183 #set up range from param
172 184 since_id = params.fetch(:since_id, 0).to_i
@@ -201,7 +213,7
201 213 end
202 214
203 215 def random_all_passwords
204 - users = User.find(:all)
216 + users = User.all
205 217 @prefix = params[:prefix] || ''
206 218 @non_admin_users = User.find_non_admin_with_prefix(@prefix)
207 219 @changed = false
@@ -324,7 +336,7
324 336 # admin management
325 337
326 338 def admin
327 - @admins = User.find(:all).find_all {|user| user.admin? }
339 + @admins = User.all.find_all {|user| user.admin? }
328 340 end
329 341
330 342 def grant_admin
@@ -395,6 +407,39
395 407 redirect_to :action => 'mass_mailing'
396 408 end
397 409
410 + #bulk manage
411 + def bulk_manage
412 +
413 + begin
414 + @users = User.where('login REGEXP ?',params[:regex]) if params[:regex]
415 + @users.count if @users #i don't know why I have to call count, but if I won't exception is not raised
416 + rescue Exception
417 + flash[:error] = 'Regular Expression is malformed'
418 + @users = nil
419 + end
420 +
421 + if params[:commit]
422 + @action = {}
423 + @action[:set_enable] = params[:enabled]
424 + @action[:enabled] = params[:enable] == "1"
425 + @action[:gen_password] = params[:gen_password]
426 + end
427 +
428 + if params[:commit] == "Perform"
429 + if @action[:set_enable]
430 + @users.update_all(enabled: @action[:enabled])
431 + end
432 + if @action[:gen_password]
433 + @users.each do |u|
434 + password = random_password
435 + u.password = password
436 + u.password_confirmation = password
437 + u.save
438 + end
439 + end
440 + end
441 + end
442 +
398 443 protected
399 444
400 445 def random_password(length=5)
@@ -521,7 +566,7
521 566 row << sc[i].login
522 567 row << sc[i].full_name
523 568 row << sc[i].activated
524 - row << (sc[i].try(:contest_stat).try(:started_at).nil? 'no' : 'yes')
569 + row << (sc[i].try(:contest_stat).try(:started_at).nil? ? 'no' : 'yes')
525 570 row << sc[i].contests.collect {|c| c.name}.join(', ')
526 571 else
527 572 row << sc[i][0]
@@ -535,4 +580,9
535 580 end
536 581 end
537 582 end
583 +
584 + private
585 + def user_params
586 + params.require(:user).permit(:login,:password,:password_confirmation,:email, :alias, :full_name,:remark)
538 587 end
588 + end
@@ -52,7 +52,7
52 52 redirect_to :controller => 'main', :action => 'login'
53 53 return
54 54 end
55 - @user = User.new(params[:user])
55 + @user = User.new(user_params)
56 56 @user.password_confirmation = @user.password = User.random_password
57 57 @user.activated = false
58 58 if (@user.valid?) and (@user.save)
@@ -210,5 +210,9
210 210 admin_authorization
211 211 end
212 212
213 + private
214 + def user_params
215 + params.require(:user).permit(:login, :full_name, :email)
216 + end
213 217
214 218 end
@@ -196,4 +196,26
196 196 markdown.to_html.html_safe
197 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)
199 209 end
210 +
211 + def flash_messages
212 + flash.each do |msg_type, message|
213 + concat(content_tag(:div, message, class: "alert #{bootstrap_class_for(msg_type)} fade in") do
214 + concat content_tag(:button, 'x', class: "close", data: { dismiss: 'alert' })
215 + concat message
216 + end)
217 + end
218 + nil
219 + end
220 +
221 + end
@@ -1,21 +1,15
1 1 class Announcement < ActiveRecord::Base
2 2
3 - def self.find_published(contest_started=false)
3 + def self.published(contest_started=false)
4 4 if contest_started
5 - Announcement.find(:all,
6 - :conditions => "(published = 1) AND (frontpage = 0)",
7 - :order => "created_at DESC")
5 + where(published: true).where(frontpage: false).order(created_at: :desc)
8 6 else
9 - Announcement.find(:all,
10 - :conditions => "(published = 1) AND (frontpage = 0) AND (contest_only = 0)",
11 - :order => "created_at DESC")
7 + where(published: true).where(frontpage: false).where(contest_only: false).order(created_at: :desc)
12 8 end
13 9 end
14 10
15 - def self.find_for_frontpage
16 - Announcement.find(:all,
17 - :conditions => "(published = 1) AND (frontpage = 1)",
18 - :order => "created_at DESC")
11 + def self.frontpage
12 + where(published: 1).where(frontpage: 1).order(created_at: :desc)
19 13 end
20 14
21 15 end
@@ -3,6 +3,6
3 3 has_and_belongs_to_many :users
4 4 has_and_belongs_to_many :problems
5 5
6 - scope :enabled, :conditions => {:enabled => true}
6 + scope :enabled, -> { where(enabled: true) }
7 7
8 8 end
@@ -10,6 +10,8
10 10 MULTICONTESTS_KEY = 'system.multicontests'
11 11 CONTEST_TIME_LIMIT_KEY = 'contest.time_limit'
12 12 MULTIPLE_IP_LOGIN_KEY = 'right.multiple_ip_login'
13 + VIEW_TESTCASE = 'right.view_testcase'
14 + SINGLE_USER_KEY = 'system.single_user_mode'
13 15
14 16 cattr_accessor :config_cache
15 17 cattr_accessor :task_grading_info_cache
@@ -70,6 +72,10
70 72 return (get(SYSTEM_MODE_CONF_KEY)=='analysis')
71 73 end
72 74
75 + def self.show_testcase
76 + return get(VIEW_TESTCASE)
77 + end
78 +
73 79 def self.allow_test_request(user)
74 80 mode = get(SYSTEM_MODE_CONF_KEY)
75 81 early_timeout = get(TEST_REQUEST_EARLY_TIMEOUT_KEY)
@@ -152,7 +158,7
152 158
153 159 def self.read_config
154 160 GraderConfiguration.config_cache = {}
155 - GraderConfiguration.find(:all).each do |conf|
161 + GraderConfiguration.all.each do |conf|
156 162 key = conf.key
157 163 val = conf.value
158 164 GraderConfiguration.config_cache[key] = GraderConfiguration.convert_type(val,conf.value_type)
@@ -1,11 +1,7
1 1 class GraderProcess < ActiveRecord::Base
2 2
3 3 def self.find_by_host_and_pid(host,pid)
4 - return GraderProcess.find(:first,
5 - :conditions => {
6 - :host => host,
7 - :pid => pid
8 - })
4 + return GraderProcess.where(host:host).where(pid: pid).first
9 5 end
10 6
11 7 def self.register(host,pid,mode)
@@ -27,20 +23,15
27 23 end
28 24
29 25 def self.find_running_graders
30 - GraderProcess.find(:all,
31 - :conditions => {:terminated => 0})
26 + where(terminated: false)
32 27 end
33 28
34 29 def self.find_terminated_graders
35 - GraderProcess.find(:all,
36 - :conditions => "`terminated`")
30 + where(terminated: true)
37 31 end
38 32
39 33 def self.find_stalled_process
40 - GraderProcess.find(:all,
41 - :conditions => ["(`terminated` = 0) AND active AND " +
42 - "(updated_at < ?)",
43 - Time.now.gmtime - GraderProcess.stalled_time])
34 + where(terminated: false).where(active: true).where("updated_at < ?",Time.now.gmtime - GraderProcess.stalled_time)
44 35 end
45 36
46 37 def report_active(task=nil)
@@ -4,7 +4,7
4 4
5 5 def self.cache_ext_hash
6 6 @@languages_by_ext = {}
7 - Language.find(:all).each do |language|
7 + Language.all.each do |language|
8 8 language.common_ext.split(',').each do |ext|
9 9 @@languages_by_ext[ext] = language
10 10 end
@@ -1,5 +1,4
1 1 class Login < ActiveRecord::Base
2 2 belongs_to :user
3 3
4 - attr_accessible :ip_address, :logged_in_at, :user_id
5 4 end
@@ -23,10 +23,8
23 23 end
24 24
25 25 def self.find_all_system_unreplied_messages
26 - self.find(:all,
27 - :conditions => 'ISNULL(receiver_id) ' +
28 - 'AND (ISNULL(replied) OR replied=0)',
29 - :order => 'created_at')
26 + where('ISNULL(receiver_id) ' +
27 + 'AND (ISNULL(replied) OR replied=0)')
30 28 end
31 29
32 30 def self.build_replying_message_hierarchy(*args)
@@ -6,16 +6,17
6 6 has_many :testcases, :dependent => :destroy
7 7
8 8 validates_presence_of :name
9 - validates_format_of :name, :with => /^\w+$/
9 + validates_format_of :name, :with => /\A\w+\z/
10 10 validates_presence_of :full_name
11 11
12 - scope :available, :conditions => {:available => true}
12 + scope :available, -> { where(available: true) }
13 13
14 14 DEFAULT_TIME_LIMIT = 1
15 15 DEFAULT_MEMORY_LIMIT = 32
16 16
17 - def self.find_available_problems
18 - Problem.available.all(:order => "date_added DESC, name ASC")
17 + def self.available_problems
18 + available.order(date_added: :desc).order(:name)
19 + #Problem.available.all(:order => "date_added DESC, name ASC")
19 20 end
20 21
21 22 def self.create_from_import_form_params(params, old_problem=nil)
@@ -60,7 +61,9
60 61 result = Hash.new
61 62 #total number of submission
62 63 result[:total_sub] = Submission.where(problem_id: self.id).count
63 - result[:attempted_user] = Submission.where(problem_id: self.id).group_by(:user_id)
64 + result[:attempted_user] = Submission.where(problem_id: self.id).group(:user_id)
65 + result[:pass] = Submission.where(problem_id: self.id).where("points >= ?",self.full_score).count
66 + return result
64 67 end
65 68
66 69 def long_name
@@ -13,14 +13,12
13 13 validate :must_have_valid_problem
14 14 validate :must_specify_language
15 15
16 + has_one :task
17 +
16 18 before_save :assign_latest_number_if_new_recond
17 19
18 20 def self.find_last_by_user_and_problem(user_id, problem_id)
19 - last_sub = find(:first,
20 - :conditions => {:user_id => user_id,
21 - :problem_id => problem_id},
22 - :order => 'number DESC')
23 - return last_sub
21 + where("user_id = ? AND problem_id = ?",user_id,problem_id).last
24 22 end
25 23
26 24 def self.find_all_last_by_problem(problem_id)
@@ -43,7 +41,7
43 41
44 42 def self.find_last_for_all_available_problems(user_id)
45 43 submissions = Array.new
46 - problems = Problem.find_available_problems
44 + problems = Problem.available_problems
47 45 problems.each do |problem|
48 46 sub = Submission.find_last_by_user_and_problem(user_id, problem.id)
49 47 submissions << sub if sub!=nil
@@ -52,20 +50,11
52 50 end
53 51
54 52 def self.find_by_user_problem_number(user_id, problem_id, number)
55 - Submission.find(:first,
56 - :conditions => {
57 - :user_id => user_id,
58 - :problem_id => problem_id,
59 - :number => number
60 - })
53 + where("user_id = ? AND problem_id = ? AND number = ?",user_id,problem_id,number).first
61 54 end
62 55
63 56 def self.find_all_by_user_problem(user_id, problem_id)
64 - Submission.find(:all,
65 - :conditions => {
66 - :user_id => user_id,
67 - :problem_id => problem_id,
68 - })
57 + where("user_id = ? AND problem_id = ?",user_id,problem_id)
69 58 end
70 59
71 60 def download_filename
@@ -1,3 +1,3
1 1 class SubmissionViewLog < ActiveRecord::Base
2 - attr_accessible :submission_id, :user_id
2 + #attr_accessible :submission_id, :user_id
3 3 end
@@ -48,10 +48,7
48 48 task = nil
49 49 begin
50 50 Task.transaction do
51 - task = Task.find(:first,
52 - :order => "created_at",
53 - :conditions => {:status=> Task::STATUS_INQUEUE},
54 - :lock => true)
51 + task = Task.where(status: Task::STATUS_INQUEUE).lock(true).first
55 52 if task!=nil
56 53 task.status = status
57 54 task.save!
@@ -16,8 +16,7
16 16 require 'fileutils'
17 17
18 18 class TestRequest < Task
19 -
20 - set_table_name "test_requests"
19 + self.table_name = "test_requests"
21 20
22 21 belongs_to :user
23 22 belongs_to :problem
@@ -38,9 +37,7
38 37 # since there will be only one grader grading TestRequest
39 38 # we do not need locking (hopefully)
40 39
41 - test_request = TestRequest.find(:first,
42 - :order => "created_at",
43 - :conditions => {:status=> Task::STATUS_INQUEUE})
40 + test_request = TestRequest.where(status: Task::STATUS_INQUEUE).first
44 41 if test_request!=nil
45 42 test_request.status = status
46 43 test_request.save!
@@ -1,4 +1,4
1 1 class Testcase < ActiveRecord::Base
2 2 belongs_to :problem
3 - attr_accessible :group, :input, :num, :score, :sol
3 + #attr_accessible :group, :input, :num, :score, :sol
4 4 end
@@ -8,30 +8,28
8 8
9 9 has_and_belongs_to_many :roles
10 10
11 - has_many :test_requests, :order => "submitted_at DESC"
11 + has_many :test_requests, -> {order(submitted_at: DESC)}
12 12
13 - has_many :messages,
13 + has_many :messages, -> { order(created_at: DESC) },
14 14 :class_name => "Message",
15 - :foreign_key => "sender_id",
16 - :order => 'created_at DESC'
15 + :foreign_key => "sender_id"
17 16
18 - has_many :replied_messages,
17 + has_many :replied_messages, -> { order(created_at: DESC) },
19 18 :class_name => "Message",
20 - :foreign_key => "receiver_id",
21 - :order => 'created_at DESC'
19 + :foreign_key => "receiver_id"
22 20
23 21 has_one :contest_stat, :class_name => "UserContestStat", :dependent => :destroy
24 22
25 23 belongs_to :site
26 24 belongs_to :country
27 25
28 - has_and_belongs_to_many :contests, :uniq => true, :order => 'name'
26 + has_and_belongs_to_many :contests, -> { order(:name); uniq}
29 27
30 - scope :activated_users, :conditions => {:activated => true}
28 + scope :activated_users, -> {where activated: true}
31 29
32 30 validates_presence_of :login
33 31 validates_uniqueness_of :login
34 - validates_format_of :login, :with => /^[\_A-Za-z0-9]+$/
32 + validates_format_of :login, :with => /\A[\_A-Za-z0-9]+\z/
35 33 validates_length_of :login, :within => 3..30
36 34
37 35 validates_presence_of :full_name
@@ -129,14 +127,14
129 127 end
130 128
131 129 def self.find_non_admin_with_prefix(prefix='')
132 - users = User.find(:all)
130 + users = User.all
133 131 return users.find_all { |u| !(u.admin?) and u.login.index(prefix)==0 }
134 132 end
135 133
136 134 # Contest information
137 135
138 136 def self.find_users_with_no_contest()
139 - users = User.find(:all)
137 + users = User.all
140 138 return users.find_all { |u| u.contests.length == 0 }
141 139 end
142 140
@@ -233,9 +231,18
233 231 return contest_problems
234 232 end
235 233
234 + def solve_all_available_problems?
235 + available_problems.each do |p|
236 + u = self
237 + sub = Submission.find_last_by_user_and_problem(u.id,p.id)
238 + return false if !p or !sub or sub.points < p.full_score
239 + end
240 + return true
241 + end
242 +
236 243 def available_problems
237 244 if not GraderConfiguration.multicontests?
238 - return Problem.find_available_problems
245 + return Problem.available_problems
239 246 else
240 247 contest_problems = []
241 248 pin = {}
@@ -1,8 +1,8
1 1
2 2 %tr
3 3 %td{:align => "center"}
4 - = submission_counter+1
5 - %td{:align => "center"}
4 + = submission.number
5 + %td.text-right
6 6 = link_to "##{submission.id}", submission_path(submission.id)
7 7 %td
8 8 = l submission.submitted_at, format: :long
@@ -2,25 +2,25
2 2 - if submission.nil?
3 3 = "-"
4 4 - else
5 - - if submission.graded_at.nil?
5 + - unless submission.graded_at
6 6 = t 'main.submitted_at'
7 7 = format_short_time(submission.submitted_at.localtime)
8 8 - else
9 - = t 'main.graded_at'
10 - = "#{format_short_time(submission.graded_at.localtime)}, "
9 + %strong= t 'main.graded_at'
10 + = "#{format_short_time(submission.graded_at.localtime)} "
11 + %br
11 12 - if GraderConfiguration['ui.show_score']
12 - = t 'main.score'
13 + %strong=t 'main.score'
13 14 = "#{(submission.points*100/submission.problem.full_score).to_i} "
14 15 = " ["
15 16 %tt
16 17 = submission.grader_comment
17 18 = "]"
19 + %br
20 + %strong View:
18 21 - if GraderConfiguration.show_grading_result
19 - = " | "
20 22 = link_to '[detailed result]', :action => 'result', :id => submission.id
21 - = " | "
22 - = link_to("[#{t 'main.cmp_msg'}]", {:action => 'compiler_msg', :id => submission.id}, {:popup => true})
23 - = " | "
24 - = link_to("[#{t 'main.src_link'}]",{:action => 'source', :id => submission.id})
25 - //= " | "
26 - //= link_to "[#{t 'main.submissions_link'}]", main_submission_path(submission.problem.id)
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.src_link'}", download_submission_path(submission.id), class: 'btn btn-xs btn-info'
25 + = link_to "#{t 'main.submissions_link'}", problem_submissions_path(problem_id), class: 'btn btn-xs btn-info'
26 +
@@ -3,15 +3,18
3 3
4 4 %h1 System configuration
5 5
6 - %table.info
7 - %tr.info-head
8 - %th Key
9 - %th Type
10 - %th Value
6 + - @group.each do |g|
7 + %h2= g
8 + %table.table.table-striped
9 + %thead
10 + %th{style: 'width: 25%'} Key
11 + %th{style: 'width: 10%'}Type
12 + %th{style: 'width: 15%'} Value
11 13 %th Description
12 14 - @configurations.each do |conf|
15 + - next if conf.key[0...(conf.key.index('.'))] != g
13 16 - @grader_configuration = conf
14 - %tr{:class => cycle("info-odd", "info-even")}
17 + %tr
15 18 %td
16 19 /= in_place_editor_field :grader_configuration, :key, {}, :rows=>1
17 20 = @grader_configuration.key
@@ -54,8 +54,8
54 54 - @submission.each do |sub|
55 55 %tr.inactive
56 56 %td= link_to sub.id, submission_path(sub.id)
57 - %td= ("" unless sub.user) || link_to sub.try(:user).try(:full_name), stat_user_path(sub.user.id)
58 - %td= ("" unless sub.problem) || link_to sub.try(:problem).try(:full_name), stat_problem_path(sub.problem.id)
57 + %td= ("" unless sub.user) || link_to(sub.try(:user).try(:full_name), stat_user_path(sub.user.id))
58 + %td= ("" unless sub.problem) || link_to(sub.try(:problem).try(:full_name), stat_problem_path(sub.problem.id))
59 59 %td= "#{time_ago_in_words(sub.submitted_at)} ago"
60 60 %td= sub.graded_at ? "#{time_ago_in_words(sub.graded_at)} ago" : " "
61 61 %td= sub.grader_comment
@@ -72,8 +72,8
72 72 - @backlog_submission.each do |sub|
73 73 %tr.inactive
74 74 %td= link_to sub.id, submission_path(sub.id)
75 - %td= ("" unless sub.user) || link_to sub.try(:user).try(:full_name), stat_user_path(sub.user.id)
76 - %td= ("" unless sub.problem) || link_to sub.try(:problem).try(:full_name), stat_problem_path(sub.problem.id)
75 + %td= ("" unless sub.user) || link_to( sub.try(:user).try(:full_name), stat_user_path(sub.user.id))
76 + %td= ("" unless sub.problem) || link_to( sub.try(:problem).try(:full_name), stat_problem_path(sub.problem.id))
77 77 %td= "#{time_ago_in_words(sub.submitted_at)} ago"
78 78 %td= sub.graded_at ? "#{time_ago_in_words(sub.graded_at)} ago" : " "
79 79 %td= sub.grader_comment
@@ -2,20 +2,26
2 2 %nav
3 3 .container-fluid
4 4 .navbar-header
5 + %button.navbar-toggle.collapsed{ data: {toggle: 'collapse', target: '#navbar-collapse'} }
6 + %span.sr-only Togggle Navigation
7 + %span.icon-bar
8 + %span.icon-bar
9 + %span.icon-bar
5 10 %a.navbar-brand{href: main_list_path}
6 11 %span.glyphicon.glyphicon-home
7 12 MAIN
8 - .collapse.navbar-collapse
13 + .collapse.navbar-collapse#navbar-collapse
9 14 %ul.nav.navbar-nav
15 + / submission
10 16 - if (@current_user!=nil) and (GraderConfiguration.show_tasks_to?(@current_user))
11 - //= add_menu("#{I18n.t 'menu.tasks'}", 'tasks', 'list')
12 17 %li.dropdown
13 18 %a.dropdown-toggle{href: '#', data: {toggle:'dropdown'}, aria: {haspopup:"true", expanded:"false"}, role: "button"}
14 19 = "#{I18n.t 'menu.submissions'}"
15 20 %span.caret
16 21 %ul.dropdown-menu
17 - = add_menu("View", 'main', 'submission')
22 + = add_menu("View", 'submissions', 'index')
18 23 = add_menu("Self Test", 'test', 'index')
24 + / hall of fame
19 25 - if GraderConfiguration['right.user_hall_of_fame']
20 26 = add_menu("#{I18n.t 'menu.hall_of_fame'}", 'report', 'problem_hof')
21 27 / display MODE button (with countdown in contest mode)
@@ -32,6 +38,7
32 38 $("#countdown").countdown({until: "+#{@current_user.contest_time_left.to_i}s", layout: 'Time left: {hnn}:{mnn}:{snn}'});
33 39 / admin section
34 40 - if (@current_user!=nil) and (session[:admin])
41 + / management
35 42 %li.dropdown
36 43 %a.dropdown-toggle{href: '#', data: {toggle:'dropdown'}, aria: {haspopup:"true", expanded:"false"}, role: "button"}
37 44 Manage
@@ -47,12 +54,14
47 54 %li.divider{role: 'separator'}
48 55 = add_menu( 'Sites', 'sites', 'index')
49 56 = add_menu( 'Contests', 'contest_management', 'index')
57 + / report
50 58 %li.dropdown
51 59 %a.dropdown-toggle{href: '#', data: {toggle:'dropdown'}, aria: {haspopup:"true", expanded:"false"}, role: "button"}
52 60 Report
53 61 %span.caret
54 62 %ul.dropdown-menu
55 - = add_menu( 'Results', 'report', 'current_score')
63 + = add_menu( 'Current Score', 'report', 'current_score')
64 + = add_menu( 'Score Report', 'report', 'max_score')
56 65 = add_menu( 'Report', 'report', 'multiple_login')
57 66 - if (ungraded = Submission.where('graded_at is null').where('submitted_at < ?', 1.minutes.ago).count) > 0
58 67 =link_to "#{ungraded} backlogs!",
@@ -11,5 +11,6
11 11 %body
12 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 16 = yield
@@ -12,7 +12,7
12 12 %hr/
13 13
14 14 %div{ :style => "border: solid 1px gray; padding: 4px; background: #eeeeff;"}
15 - = form_tag :controller => 'login', :action => 'login' do
15 + = form_tag login_login_path do
16 16 %table
17 17 %tr
18 18 %td{:align => "right"}
@@ -1,8 +1,12
1 1 %tr
2 2 %td
3 + - if @current_user and @current_user.admin?
4 + = link_to problem.name, stat_problem_path(problem)
5 + - else
3 6 = "#{problem.name}"
4 7 %td
5 8 = "#{problem.full_name}"
9 +
6 10 %br
7 11 = link_to_description_if_any "[#{t 'main.problem_desc'}] <span class='glyphicon glyphicon-file'></span>".html_safe, problem
8 12 %td
@@ -8,7 +8,7
8 8 %li= msg
9 9 .form-group
10 10 = label_tag :submission, 'Problem:'
11 - = select 'submission', 'problem_id', [[(t 'main.specified_in_header'),'-1']] + @problems.collect {|p| ["[#{p.name}] #{p.full_name}", p.id]}, {:selected => '-1'}, { class: 'select2 form-control' }
11 + = select 'submission', 'problem_id', [[(t 'main.specified_in_header'),'-1']] + @problems.collect {|p| ["[#{p.name}] #{p.full_name}", p.id]}, {:selected => '-1'}, { class: 'select2 form-control', style: "width: 100%" }
12 12 .form-group
13 13 = label_tag :file, 'File:'
14 14 .input-group
@@ -10,7 +10,7
10 10 = "#{format_short_time(submission.graded_at.localtime)} "
11 11 %br
12 12 - if GraderConfiguration['ui.show_score']
13 - =t 'main.score'
13 + %strong=t 'main.score'
14 14 = "#{(submission.points*100/submission.problem.full_score).to_i} "
15 15 = " ["
16 16 %tt
@@ -20,7 +20,10
20 20 %strong View:
21 21 - if GraderConfiguration.show_grading_result
22 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 25 = link_to "#{t 'main.src_link'}",{:action => 'source', :id => submission.id}, class: 'btn btn-xs btn-info'
25 26 = link_to "#{t 'main.submissions_link'}", problem_submissions_path(problem_id), class: 'btn btn-xs btn-info'
27 + - if GraderConfiguration.show_testcase
28 + = link_to "testcases", show_problem_testcases_path(problem_id), class: 'btn btn-xs btn-info'
26 29
@@ -43,6 +43,7
43 43 .panel.panel-info
44 44 .panel-heading
45 45 Announcement
46 + = link_to 'Manage', announcements_path, class: 'btn btn-xs btn-default'
46 47 %ul.list-group
47 48 = render :partial => 'announcement', :collection => @announcements
48 49
@@ -50,3 +51,14
50 51 = "Announcement.refreshUrl = '#{url_for :controller => 'main', :action => 'announcements'}';"
51 52 Announcement.registerRefreshEventTimer();
52 53
54 + .modal.fade#compiler{tabindex: -1,role: 'dialog'}
55 + .modal-dialog.modal-lg{role:'document'}
56 + .modal-content
57 + .modal-header
58 + %button.close{type: 'button', data: {dismissed: :modal}, aria: {label: 'close'}}
59 + %span{aria: {hidden: 'true'}, data: {dismiss: 'modal'}} &times;
60 + %h4 Compiler message
61 + .modal-body
62 + %pre#compiler_msg
63 + .modal-footer
64 + %button.btn.btn-default{type: 'button', data: {dismiss: 'modal'}} Close
@@ -26,6 +26,9
26 26 Avail?
27 27 %sup{class: 'text-primary',data: {toggle: 'tooltip'}, title: 'Let user submits to this problem?' } [?]
28 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 32 Test?
30 33 %sup{class: 'text-primary',data: {toggle: 'tooltip'}, title: 'Let user uses test interface on this problem?' } [?]
31 34 - if GraderConfiguration.multicontests?
@@ -38,6 +41,7
38 41 %td.text-right= problem.full_score #in_place_editor_field :problem, :full_score, {}, :rows=>1
39 42 %td= problem.date_added
40 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 45 %td= toggle_button(@problem.test_allowed?, toggle_test_problem_path(@problem), "problem-test-#{@problem.id}")
42 46 - if GraderConfiguration.multicontests?
43 47 %td
@@ -21,4 +21,4
21 21 </p>
22 22
23 23 <%= link_to 'Edit', :action => 'edit', :id => @problem %> |
24 - <%= link_to 'Back', :action => 'list' %>
24 + <%= link_to 'Back', problems_path %>
@@ -3,12 +3,12
3 3 %tr
4 4 %th Login
5 5 %th Name
6 - %th Activated?
7 - %th Logged_in
8 - %th Contest(s)
6 + / %th Activated?
7 + / %th Logged_in
8 + / %th Contest(s)
9 9 %th Remark
10 10 - @problems.each do |p|
11 - %th.text-right= p.name
11 + %th.text-right= p.name.gsub('_',' ')
12 12 %th.text-right Total
13 13 %th.text-right Passed
14 14 %tbody
@@ -17,11 +17,11
17 17 - total,num_passed = 0,0
18 18 - sc.each_index do |i|
19 19 - if i == 0
20 - %td= link_to sc[i].login, controller: 'users', action: 'profile', id: sc[i]
20 + %td= link_to sc[i].login, stat_user_path(sc[i])
21 21 %td= sc[i].full_name
22 - %td= sc[i].activated
23 - %td= sc[i].try(:contest_stat).try(:started_at) ? 'yes' : 'no'
24 - %td= sc[i].contests.collect {|c| c.name}.join(', ')
22 + / %td= sc[i].activated
23 + / %td= sc[i].try(:contest_stat).try(:started_at) ? 'yes' : 'no'
24 + / %td= sc[i].contests.collect {|c| c.name}.join(', ')
25 25 %td= sc[i].remark
26 26 - else
27 27 %td.text-right= sc[i][0]
@@ -44,7 +44,7
44 44 %tr
45 45 %td.info_param Best Runtime
46 46 %td
47 - by #{link_to @best[:runtime][:user], controller:'users', action:'profile', id:@best[:memory][:user_id]}
47 + by #{link_to @best[:runtime][:user], stat_user_path(@best[:runtime][:user_id])}
48 48 %br
49 49 using <span class="text-success">#{@best[:runtime][:lang]}</span>
50 50 %br
@@ -62,7 +62,7
62 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 63 [?]
64 64 %td
65 - by #{link_to @best[:memory][:user], controller:'users', action:'profile', id:@best[:memory][:user_id]}
65 + by #{link_to @best[:memory][:user], stat_user_path(@best[:memory][:user_id])}
66 66 %br
67 67 using <span class="text-success">#{@best[:memory][:lang]}</span>
68 68 %br
@@ -74,7 +74,7
74 74 %tr
75 75 %td.info_param Shortest Code
76 76 %td
77 - by #{link_to @best[:length][:user], controller:'users', action:'profile', id:@best[:length][:user_id]}
77 + by #{link_to @best[:length][:user], stat_user_path(@best[:length][:user_id])}
78 78 %br
79 79 using <span class="text-success">#{@best[:length][:lang]}</span>
80 80 %br
@@ -87,7 +87,7
87 87 %td.info_param First solver
88 88 %td
89 89 - if @best[:first][:user] != '(NULL)'
90 - #{link_to @best[:first][:user], controller:'users', action:'profile', id:@best[:first][:user_id]} is the first solver
90 + #{link_to @best[:first][:user], stat_user_path(@best[:first][:user_id])} is the first solver
91 91 %br
92 92 using <span class="text-success">#{@best[:first][:lang]}</span>
93 93 %br
@@ -113,23 +113,23
113 113 %tr
114 114 %td= lang
115 115 %td
116 - = link_to value[:runtime][:user], controller: 'users', action: 'profile', id: value[:runtime][:user_id]
116 + = link_to value[:runtime][:user], stat_user_path(value[:runtime][:user_id])
117 117 %br
118 118 = "#{(value[:runtime][:value] * 1000).to_i} @"
119 119 = link_to "#" + value[:runtime][:sub_id].to_s, submission_path( value[:runtime][:sub_id])
120 120 %td
121 - = link_to value[:memory][:user], controller: 'users', action: 'profile', id: value[:memory][:user_id]
121 + = link_to value[:memory][:user], stat_user_path( value[:memory][:user_id])
122 122 %br
123 123 = "#{number_with_delimiter(value[:memory][:value])} @"
124 124 = link_to "#" + value[:memory][:sub_id].to_s, submission_path(value[:memory][:sub_id])
125 125 %td
126 - = link_to value[:length][:user], controller: 'users', action: 'profile', id: value[:length][:user_id]
126 + = link_to value[:length][:user], stat_user_path(value[:length][:user_id])
127 127 %br
128 128 = "#{value[:length][:value]} @"
129 129 = link_to "#" + value[:length][:sub_id].to_s, submission_path(value[:length][:sub_id])
130 130 %td
131 131 - if value[:first][:user] != '(NULL)' #TODO: i know... this is wrong...
132 - = link_to value[:first][:user], controller: 'users', action: 'profile', id: value[:first][:user_id]
132 + = link_to value[:first][:user], stat_user_path(value[:first][:user_id])
133 133 %br
134 134 = "#{value[:first][:value]} @"
135 135 = link_to "#" + value[:first][:sub_id].to_s, submission_path( value[:first][:sub_id])
@@ -22,10 +22,10
22 22 Input minimum and maximum range of submission ID that should be included. A blank value for min and max means -1 and infinity, respectively.
23 23 .form-group
24 24 = label_tag :from, "Min"
25 - = text_field_tag 'from_id', nil, class: "form-control"
25 + = text_field_tag 'from_id', @since_id, class: "form-control"
26 26 .form-group
27 27 = label_tag :from, "Max"
28 - = text_field_tag 'to_id', nil, class: "form-control"
28 + = text_field_tag 'to_id', @until_id, class: "form-control"
29 29 .col-md-4
30 30 .panel.panel-primary
31 31 .panel-heading
@@ -1,7 +1,7
1 1 %h2 Live submit
2 2 %br
3 3
4 - %textarea#text_haha{style: "display:none"}~ @source
4 + %textarea#text_sourcecode{style: "display:none"}~ @source
5 5 .container
6 6 .row
7 7 .col-md-12
@@ -28,10 +28,11
28 28 .panel.panel-info
29 29 .panel-heading
30 30 Latest Submission Status
31 + = link_to "Refresh",get_latest_submission_status_submissions_path(@submission.user,@problem), class: "btn btn-default btn-sm", remote: true if @submission
31 32 .panel-body
32 33 - if @submission
33 34 = render :partial => 'submission_short',
34 - :locals => {:submission => @submission, :problem_name => @problem.name }
35 + :locals => {submission: @submission, problem_name: @problem.name, problem_id: @problem.id }
35 36 .row
36 37 .col-md-12
37 38 %h2 Console
@@ -40,7 +41,7
40 41 :javascript
41 42 $(document).ready(function() {
42 43 e = ace.edit("editor")
43 - e.setValue($("#text_haha").val());
44 + e.setValue($("#text_sourcecode").val());
44 45 e.gotoLine(1);
45 46 $("#language_id").trigger('change');
46 47 brython();
@@ -1,2 +1,2
1 - :javascript
1 + :plain
2 2 $("#latest_status").html("#{j render({partial: 'submission_short', locals: {submission: @submission, problem_name: @problem.name}})}")
@@ -18,7 +18,7
18 18 %table.table
19 19 %thead
20 20 %th No.
21 - %th #
21 + %th.text-right #
22 22 %th At
23 23 %th Source
24 24 %th Result
@@ -6,6 +6,8
6 6
7 7 //%div.highlight{:style => "border: 1px solid black;"}
8 8 //=@formatted_code.html_safe
9 +
10 +
9 11 .containter
10 12 .row
11 13 .col-md-7
@@ -64,7 +66,7
64 66 %tr
65 67 %td.text-right
66 68 %strong Points
67 - %td #{@submission.points}/#{@submission.problem.full_score}
69 + %td #{@submission.points}/#{@submission.try(:problem).try(:full_score)}
68 70 %tr
69 71 %td.text-right
70 72 %strong Comment
@@ -81,9 +83,30
81 83 %td.text-right
82 84 %strong Compiler result
83 85 %td
84 - %pre= @submission.compiler_message
86 + %button.btn.btn-info.btn-xs{type: 'button', data: {toggle: 'modal', target: '#compiler'}}
87 + view
85 88 - if session[:admin]
86 89 %tr
87 90 %td.text-right
88 91 %strong IP
89 92 %td #{@submission.ip_address}
93 + %tr
94 + %td.text-right
95 + %strong Grading Task Status
96 + %td
97 + = @task.status_str if @task
98 + - if session[:admin]
99 + = link_to "rejudge", rejudge_submission_path, data: {remote: true}, class: 'btn btn-info btn-xs'
100 +
101 +
102 + .modal.fade#compiler{tabindex: -1,role: 'dialog'}
103 + .modal-dialog.modal-lg{role:'document'}
104 + .modal-content
105 + .modal-header
106 + %button.close{type: 'button', data: {dismissed: :modal}, aria: {label: 'close'}}
107 + %span{aria: {hidden: 'true'}, data: {dismiss: 'modal'}} &times;
108 + %h4 Compiler message
109 + .modal-body
110 + %pre#compiler_msg= @submission.compiler_message
111 + .modal-footer
112 + %button.btn.btn-default{type: 'button', data: {dismiss: 'modal'}} Close
@@ -42,6 +42,7
42 42 = link_to '+ New user', { :action => 'new' }, { class: 'btn btn-success '}
43 43 = link_to '+ New list of users', { :action => 'new_list' }, { class: 'btn btn-success '}
44 44 = link_to 'View administrators',{ :action => 'admin'}, { class: 'btn btn-default '}
45 + = link_to 'Bulk Manage', bulk_manage_user_admin_path , { class: 'btn btn-default '}
45 46 = link_to 'Random passwords',{ :action => 'random_all_passwords'}, { class: 'btn btn-default '}
46 47 = link_to 'View active users',{ :action => 'active'}, { class: 'btn btn-default '}
47 48 = link_to 'Mass mailing',{ :action => 'mass_mailing'}, { class: 'btn btn-default '}
@@ -84,7 +85,7
84 85 %th
85 86 - for user in @users
86 87 %tr
87 - %td= link_to user.login, controller: :users, :action => 'profile', :id => user
88 + %td= link_to user.login, stat_user_path(user)
88 89 %td= user.full_name
89 90 %td= user.email
90 91 %td= user.remark
@@ -1,8 +1,9
1 1 <h1>Adding list of users</h1>
2 2
3 3 <%= form_tag :action => 'create_from_list' do %>
4 - <%= submit_tag 'create users' %><br/>
5 - List of user information in this format: <tt>user_id,name(,passwd(,alias))</tt><br/>
6 - Note that <tt>passwd</tt> and <tt>alias</tt> is optional.<br/>
4 + <%= submit_tag 'create users',class: 'btn btn-success'%><br/>
5 + List of user information in this format: <tt>user_id,name(,passwd(,alias(,remark)))</tt><br/>
6 + Note that <tt>passwd, alias</tt> and <tt> remark </tt>is optional.<br />
7 + When <tt>passwd</tt> or <tt>alias</tt> is empty, the original value will be used instead.<br/>
7 8 <%= text_area_tag 'user_list', nil, :rows => 50, :cols => 80 %>
8 9 <% end %>
@@ -6,8 +6,8
6 6 # since you don't have to restart the web server when you make code changes.
7 7 config.cache_classes = false
8 8
9 - # Log error messages when you accidentally call methods on nil.
10 - config.whiny_nils = true
9 + # Log error messages when you accidentally call methods on nil. //DEPRICATED
10 + # config.whiny_nils = true // DEPRICATED
11 11
12 12 # Show full error reports and disable caching
13 13 config.consider_all_requests_local = true
@@ -23,11 +23,11
23 23 config.action_dispatch.best_standards_support = :builtin
24 24
25 25 # Raise exception on mass assignment protection for Active Record models
26 - config.active_record.mass_assignment_sanitizer = :strict
26 + # config.active_record.mass_assignment_sanitizer = :strict //DEPRICATED
27 27
28 - # Log the query plan for queries taking more than this (works
29 - # with SQLite, MySQL, and PostgreSQL)
30 - config.active_record.auto_explain_threshold_in_seconds = 0.5
28 + # Log the query plan for queries taking more than this (works // DEPRICATED
29 + # with SQLite, MySQL, and PostgreSQL) // DEPRICATED
30 + # config.active_record.auto_explain_threshold_in_seconds = 0.5 // DEPRICATED
31 31
32 32 # Do not compress assets
33 33 config.assets.compress = false
@@ -36,5 +36,7
36 36 config.assets.debug = true
37 37
38 38 # Prevents assets from rendering twice
39 - config.serve_static_assets = true
39 + config.serve_static_files = true
40 +
41 + config.eager_load = false
40 42 end
@@ -9,7 +9,7
9 9 config.action_controller.perform_caching = true
10 10
11 11 # Disable Rails's static asset server (Apache or nginx will already do this)
12 - config.serve_static_assets = false
12 + config.serve_static_files = false
13 13
14 14 # Compress JavaScripts and CSS
15 15 config.assets.compress = true
@@ -64,4 +64,6
64 64 # Log the query plan for queries taking more than this (works
65 65 # with SQLite, MySQL, and PostgreSQL)
66 66 # config.active_record.auto_explain_threshold_in_seconds = 0.5
67 +
68 + config.eager_load = true
67 69 end
@@ -8,7 +8,7
8 8 config.cache_classes = true
9 9
10 10 # Configure static asset server for tests with Cache-Control for performance
11 - config.serve_static_assets = true
11 + config.serve_static_files = true
12 12 config.static_cache_control = "public, max-age=3600"
13 13
14 14 # Log error messages when you accidentally call methods on nil
@@ -30,8 +30,14
30 30 config.action_mailer.delivery_method = :test
31 31
32 32 # Raise exception on mass assignment protection for Active Record models
33 - config.active_record.mass_assignment_sanitizer = :strict
33 + #config.active_record.mass_assignment_sanitizer = :strict // DEPRICATED
34 34
35 35 # Print deprecation notices to the stderr
36 36 config.active_support.deprecation = :stderr
37 +
38 + config.eager_load = false
39 +
40 + #test order
41 + config.active_support.test_order = :sorted
42 +
37 43 end
@@ -3,4 +3,3
3 3 # Add new mime types for use in respond_to blocks:
4 4 # Mime::Type.register "text/richtext", :rtf
5 5 # Mime::Type.register_alias "text/html", :iphone
6 - Mime::Type.register 'application/pdf', :pdf
@@ -3,6 +3,9
3 3
4 4 root :to => 'main#login'
5 5
6 + #logins
7 + get 'login/login', to: 'login#login'
8 +
6 9 resources :contests
7 10
8 11 resources :sites
@@ -17,6 +20,7
17 20 member do
18 21 get 'toggle'
19 22 get 'toggle_test'
23 + get 'toggle_view_testcase'
20 24 get 'stat'
21 25 end
22 26 collection do
@@ -25,6 +29,17
25 29 get 'import'
26 30 get 'manage'
27 31 end
32 +
33 + end
34 +
35 + resources :testcases, only: [] do
36 + member do
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'
42 + end
28 43 end
29 44
30 45 resources :grader_configuration, controller: 'configurations'
@@ -37,6 +52,11
37 52 end
38 53
39 54 resources :submissions do
55 + member do
56 + get 'download'
57 + get 'compiler_msg'
58 + get 'rejudge'
59 + end
40 60 collection do
41 61 get 'prob/:problem_id', to: 'submissions#index', as: 'problem'
42 62 get 'direct_edit_problem/:problem_id', to: 'submissions#direct_edit_problem', as: 'direct_edit_problem'
@@ -44,14 +64,15
44 64 end
45 65 end
46 66
47 - match 'tasks/view/:file.:ext' => 'tasks#view'
48 - match 'tasks/download/:id/:file.:ext' => 'tasks#download'
49 - match 'heartbeat/:id/edit' => 'heartbeat#edit'
67 +
50 68
51 69 #main
52 70 get "main/list"
53 71 get 'main/submission(/:id)', to: 'main#submission', as: 'main_submission'
54 72
73 + #user admin
74 + get 'user_admin/bulk_manage', to: 'user_admin#bulk_manage', as: 'bulk_manage_user_admin'
75 +
55 76 #report
56 77 get 'report/current_score', to: 'report#current_score', as: 'report_current_score'
57 78 get 'report/problem_hof(/:id)', to: 'report#problem_hof', as: 'report_problem_hof'
@@ -59,15 +80,19
59 80 get 'report/max_score', to: 'report#max_score', as: 'report_max_score'
60 81 post 'report/show_max_score', to: 'report#show_max_score', as: 'report_show_max_score'
61 82
83 +
84 + #
85 + get 'tasks/view/:file.:ext' => 'tasks#view'
86 + get 'tasks/download/:id/:file.:ext' => 'tasks#download'
87 + get 'heartbeat/:id/edit' => 'heartbeat#edit'
88 +
62 89 #grader
63 90 get 'graders/list', to: 'graders#list', as: 'grader_list'
64 91
65 92
66 - match 'heartbeat/:id/edit' => 'heartbeat#edit'
67 -
68 93 # See how all your routes lay out with "rake routes"
69 94
70 95 # This is a legacy wild controller route that's not recommended for RESTful applications.
71 96 # Note: This route will make all actions in every controller accessible via GET requests.
72 - match ':controller(/:action(/:id))(.:format)'
97 + match ':controller(/:action(/:id))(.:format)', via: [:get, :post]
73 98 end
@@ -9,272 +9,275
9 9 # from scratch. The latter is a flawed and unsustainable approach (the more migrations
10 10 # you'll amass, the slower it'll run and the greater likelihood for issues).
11 11 #
12 - # It's strongly recommended to 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 => 20161014091417) do
14 + ActiveRecord::Schema.define(version: 20170427070345) do
15 15
16 - create_table "announcements", :force => true do |t|
17 - t.string "author"
18 - t.text "body"
16 + create_table "announcements", force: :cascade do |t|
17 + t.string "author", limit: 255
18 + t.text "body", limit: 65535
19 19 t.boolean "published"
20 - t.datetime "created_at", :null => false
21 - t.datetime "updated_at", :null => false
22 - t.boolean "frontpage", :default => false
23 - t.boolean "contest_only", :default => false
24 - t.string "title"
25 - t.string "notes"
20 + t.datetime "created_at", null: false
21 + t.datetime "updated_at", null: false
22 + t.boolean "frontpage", default: false
23 + t.boolean "contest_only", default: false
24 + t.string "title", limit: 255
25 + t.string "notes", limit: 255
26 26 end
27 27
28 - create_table "contests", :force => true do |t|
29 - t.string "title"
28 + create_table "contests", force: :cascade do |t|
29 + t.string "title", limit: 255
30 30 t.boolean "enabled"
31 - t.datetime "created_at", :null => false
32 - t.datetime "updated_at", :null => false
33 - t.string "name"
31 + t.datetime "created_at", null: false
32 + t.datetime "updated_at", null: false
33 + t.string "name", limit: 255
34 34 end
35 35
36 - create_table "contests_problems", :id => false, :force => true do |t|
37 - t.integer "contest_id"
38 - t.integer "problem_id"
36 + create_table "contests_problems", id: false, force: :cascade do |t|
37 + t.integer "contest_id", limit: 4
38 + t.integer "problem_id", limit: 4
39 39 end
40 40
41 - create_table "contests_users", :id => false, :force => true do |t|
42 - t.integer "contest_id"
43 - t.integer "user_id"
41 + create_table "contests_users", id: false, force: :cascade do |t|
42 + t.integer "contest_id", limit: 4
43 + t.integer "user_id", limit: 4
44 44 end
45 45
46 - create_table "countries", :force => true do |t|
47 - t.string "name"
48 - t.datetime "created_at", :null => false
49 - t.datetime "updated_at", :null => false
46 + create_table "countries", force: :cascade do |t|
47 + t.string "name", limit: 255
48 + t.datetime "created_at", null: false
49 + t.datetime "updated_at", null: false
50 50 end
51 51
52 - create_table "descriptions", :force => true do |t|
53 - t.text "body"
52 + create_table "descriptions", force: :cascade do |t|
53 + t.text "body", limit: 65535
54 54 t.boolean "markdowned"
55 - t.datetime "created_at", :null => false
56 - t.datetime "updated_at", :null => false
55 + t.datetime "created_at", null: false
56 + t.datetime "updated_at", null: false
57 57 end
58 58
59 - create_table "grader_configurations", :force => true do |t|
60 - t.string "key"
61 - t.string "value_type"
62 - t.string "value"
63 - t.datetime "created_at", :null => false
64 - t.datetime "updated_at", :null => false
65 - t.text "description"
59 + create_table "grader_configurations", force: :cascade do |t|
60 + t.string "key", limit: 255
61 + t.string "value_type", limit: 255
62 + t.string "value", limit: 255
63 + t.datetime "created_at", null: false
64 + t.datetime "updated_at", null: false
65 + t.text "description", limit: 65535
66 66 end
67 67
68 - create_table "grader_processes", :force => true do |t|
69 - t.string "host"
70 - t.integer "pid"
71 - t.string "mode"
68 + create_table "grader_processes", force: :cascade do |t|
69 + t.string "host", limit: 255
70 + t.integer "pid", limit: 4
71 + t.string "mode", limit: 255
72 72 t.boolean "active"
73 - t.datetime "created_at", :null => false
74 - t.datetime "updated_at", :null => false
75 - t.integer "task_id"
76 - t.string "task_type"
73 + t.datetime "created_at", null: false
74 + t.datetime "updated_at", null: false
75 + t.integer "task_id", limit: 4
76 + t.string "task_type", limit: 255
77 77 t.boolean "terminated"
78 78 end
79 79
80 - add_index "grader_processes", ["host", "pid"], :name => "index_grader_processes_on_ip_and_pid"
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 => true do |t|
83 - t.integer "user_id"
84 - t.string "ip_address"
85 - t.datetime "created_at", :null => false
86 - t.datetime "updated_at", :null => false
87 - t.string "status"
82 + create_table "heart_beats", force: :cascade do |t|
83 + t.integer "user_id", limit: 4
84 + t.string "ip_address", limit: 255
85 + t.datetime "created_at", null: false
86 + t.datetime "updated_at", null: false
87 + t.string "status", limit: 255
88 88 end
89 89
90 - add_index "heart_beats", ["updated_at"], :name => "index_heart_beats_on_updated_at"
90 + add_index "heart_beats", ["updated_at"], name: "index_heart_beats_on_updated_at", using: :btree
91 91
92 - create_table "languages", :force => true do |t|
93 - t.string "name", :limit => 10
94 - t.string "pretty_name"
95 - t.string "ext", :limit => 10
96 - t.string "common_ext"
92 + create_table "languages", force: :cascade do |t|
93 + t.string "name", limit: 10
94 + t.string "pretty_name", limit: 255
95 + t.string "ext", limit: 10
96 + t.string "common_ext", limit: 255
97 97 end
98 98
99 - create_table "logins", :force => true do |t|
100 - t.integer "user_id"
101 - t.string "ip_address"
102 - t.datetime "created_at", :null => false
103 - t.datetime "updated_at", :null => false
99 + create_table "logins", force: :cascade do |t|
100 + t.integer "user_id", limit: 4
101 + t.string "ip_address", limit: 255
102 + t.datetime "created_at", null: false
103 + t.datetime "updated_at", null: false
104 104 end
105 105
106 - create_table "messages", :force => true do |t|
107 - t.integer "sender_id"
108 - t.integer "receiver_id"
109 - t.integer "replying_message_id"
110 - t.text "body"
106 + create_table "messages", force: :cascade do |t|
107 + t.integer "sender_id", limit: 4
108 + t.integer "receiver_id", limit: 4
109 + t.integer "replying_message_id", limit: 4
110 + t.text "body", limit: 65535
111 111 t.boolean "replied"
112 - t.datetime "created_at", :null => false
113 - t.datetime "updated_at", :null => false
112 + t.datetime "created_at", null: false
113 + t.datetime "updated_at", null: false
114 114 end
115 115
116 - create_table "problems", :force => true do |t|
117 - t.string "name", :limit => 30
118 - t.string "full_name"
119 - t.integer "full_score"
116 + create_table "problems", force: :cascade do |t|
117 + t.string "name", limit: 30
118 + t.string "full_name", limit: 255
119 + t.integer "full_score", limit: 4
120 120 t.date "date_added"
121 121 t.boolean "available"
122 - t.string "url"
123 - t.integer "description_id"
122 + t.string "url", limit: 255
123 + t.integer "description_id", limit: 4
124 124 t.boolean "test_allowed"
125 125 t.boolean "output_only"
126 - t.string "description_filename"
126 + t.string "description_filename", limit: 255
127 + t.boolean "view_testcase"
127 128 end
128 129
129 - create_table "rights", :force => true do |t|
130 - t.string "name"
131 - t.string "controller"
132 - t.string "action"
130 + create_table "rights", force: :cascade do |t|
131 + t.string "name", limit: 255
132 + t.string "controller", limit: 255
133 + t.string "action", limit: 255
133 134 end
134 135
135 - create_table "rights_roles", :id => false, :force => true do |t|
136 - t.integer "right_id"
137 - t.integer "role_id"
136 + create_table "rights_roles", id: false, force: :cascade do |t|
137 + t.integer "right_id", limit: 4
138 + t.integer "role_id", limit: 4
138 139 end
139 140
140 - add_index "rights_roles", ["role_id"], :name => "index_rights_roles_on_role_id"
141 + add_index "rights_roles", ["role_id"], name: "index_rights_roles_on_role_id", using: :btree
141 142
142 - create_table "roles", :force => true do |t|
143 - t.string "name"
143 + create_table "roles", force: :cascade do |t|
144 + t.string "name", limit: 255
144 145 end
145 146
146 - create_table "roles_users", :id => false, :force => true do |t|
147 - t.integer "role_id"
148 - t.integer "user_id"
147 + create_table "roles_users", id: false, force: :cascade do |t|
148 + t.integer "role_id", limit: 4
149 + t.integer "user_id", limit: 4
149 150 end
150 151
151 - add_index "roles_users", ["user_id"], :name => "index_roles_users_on_user_id"
152 + add_index "roles_users", ["user_id"], name: "index_roles_users_on_user_id", using: :btree
152 153
153 - create_table "sessions", :force => true do |t|
154 - t.string "session_id"
155 - t.text "data"
154 + create_table "sessions", force: :cascade do |t|
155 + t.string "session_id", limit: 255
156 + t.text "data", limit: 65535
156 157 t.datetime "updated_at"
157 158 end
158 159
159 - add_index "sessions", ["session_id"], :name => "index_sessions_on_session_id"
160 - add_index "sessions", ["updated_at"], :name => "index_sessions_on_updated_at"
160 + add_index "sessions", ["session_id"], name: "index_sessions_on_session_id", using: :btree
161 + add_index "sessions", ["updated_at"], name: "index_sessions_on_updated_at", using: :btree
161 162
162 - create_table "sites", :force => true do |t|
163 - t.string "name"
163 + create_table "sites", force: :cascade do |t|
164 + t.string "name", limit: 255
164 165 t.boolean "started"
165 166 t.datetime "start_time"
166 - t.datetime "created_at", :null => false
167 - t.datetime "updated_at", :null => false
168 - t.integer "country_id"
169 - t.string "password"
167 + t.datetime "created_at", null: false
168 + t.datetime "updated_at", null: false
169 + t.integer "country_id", limit: 4
170 + t.string "password", limit: 255
170 171 end
171 172
172 - create_table "submission_view_logs", :force => true do |t|
173 - t.integer "user_id"
174 - t.integer "submission_id"
175 - t.datetime "created_at", :null => false
176 - t.datetime "updated_at", :null => false
173 + create_table "submission_view_logs", force: :cascade do |t|
174 + t.integer "user_id", limit: 4
175 + t.integer "submission_id", limit: 4
176 + t.datetime "created_at", null: false
177 + t.datetime "updated_at", null: false
177 178 end
178 179
179 - create_table "submissions", :force => true do |t|
180 - t.integer "user_id"
181 - t.integer "problem_id"
182 - t.integer "language_id"
183 - t.text "source"
184 - t.binary "binary"
180 + create_table "submissions", force: :cascade do |t|
181 + t.integer "user_id", limit: 4
182 + t.integer "problem_id", limit: 4
183 + t.integer "language_id", limit: 4
184 + t.text "source", limit: 65535
185 + t.binary "binary", limit: 65535
185 186 t.datetime "submitted_at"
186 187 t.datetime "compiled_at"
187 - t.text "compiler_message"
188 + t.text "compiler_message", limit: 65535
188 189 t.datetime "graded_at"
189 - t.integer "points"
190 - t.text "grader_comment"
191 - t.integer "number"
192 - t.string "source_filename"
193 - t.float "max_runtime"
194 - t.integer "peak_memory"
195 - t.integer "effective_code_length"
196 - t.string "ip_address"
190 + t.integer "points", limit: 4
191 + t.text "grader_comment", limit: 65535
192 + t.integer "number", limit: 4
193 + t.string "source_filename", limit: 255
194 + t.float "max_runtime", limit: 24
195 + t.integer "peak_memory", limit: 4
196 + t.integer "effective_code_length", limit: 4
197 + t.string "ip_address", limit: 255
197 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
200 - add_index "submissions", ["user_id", "problem_id"], :name => "index_submissions_on_user_id_and_problem_id"
200 + add_index "submissions", ["user_id", "problem_id", "number"], name: "index_submissions_on_user_id_and_problem_id_and_number", unique: true, 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 => true do |t|
203 - t.integer "submission_id"
203 + create_table "tasks", force: :cascade do |t|
204 + t.integer "submission_id", limit: 4
204 205 t.datetime "created_at"
205 - t.integer "status"
206 + t.integer "status", limit: 4
206 207 t.datetime "updated_at"
207 208 end
208 209
209 - create_table "test_pairs", :force => true do |t|
210 - t.integer "problem_id"
211 - t.text "input", :limit => 16777215
212 - t.text "solution", :limit => 16777215
213 - t.datetime "created_at", :null => false
214 - t.datetime "updated_at", :null => false
210 + add_index "tasks", ["submission_id"], name: "index_tasks_on_submission_id", using: :btree
211 +
212 + create_table "test_pairs", force: :cascade do |t|
213 + t.integer "problem_id", limit: 4
214 + t.text "input", limit: 16777215
215 + t.text "solution", limit: 16777215
216 + t.datetime "created_at", null: false
217 + t.datetime "updated_at", null: false
215 218 end
216 219
217 - create_table "test_requests", :force => true do |t|
218 - t.integer "user_id"
219 - t.integer "problem_id"
220 - t.integer "submission_id"
221 - t.string "input_file_name"
222 - t.string "output_file_name"
223 - t.string "running_stat"
224 - t.integer "status"
225 - t.datetime "updated_at", :null => false
220 + create_table "test_requests", force: :cascade do |t|
221 + t.integer "user_id", limit: 4
222 + t.integer "problem_id", limit: 4
223 + t.integer "submission_id", limit: 4
224 + t.string "input_file_name", limit: 255
225 + t.string "output_file_name", limit: 255
226 + t.string "running_stat", limit: 255
227 + t.integer "status", limit: 4
228 + t.datetime "updated_at", null: false
226 229 t.datetime "submitted_at"
227 230 t.datetime "compiled_at"
228 - t.text "compiler_message"
231 + t.text "compiler_message", limit: 65535
229 232 t.datetime "graded_at"
230 - t.string "grader_comment"
231 - t.datetime "created_at", :null => false
232 - t.float "running_time"
233 - t.string "exit_status"
234 - t.integer "memory_usage"
233 + t.string "grader_comment", limit: 255
234 + t.datetime "created_at", null: false
235 + t.float "running_time", limit: 24
236 + t.string "exit_status", limit: 255
237 + t.integer "memory_usage", limit: 4
235 238 end
236 239
237 - add_index "test_requests", ["user_id", "problem_id"], :name => "index_test_requests_on_user_id_and_problem_id"
240 + add_index "test_requests", ["user_id", "problem_id"], name: "index_test_requests_on_user_id_and_problem_id", using: :btree
238 241
239 - create_table "testcases", :force => true do |t|
240 - t.integer "problem_id"
241 - t.integer "num"
242 - t.integer "group"
243 - t.integer "score"
244 - t.text "input"
245 - t.text "sol"
246 - t.datetime "created_at", :null => false
247 - t.datetime "updated_at", :null => false
242 + create_table "testcases", force: :cascade do |t|
243 + t.integer "problem_id", limit: 4
244 + t.integer "num", limit: 4
245 + t.integer "group", limit: 4
246 + t.integer "score", limit: 4
247 + t.text "input", limit: 4294967295
248 + t.text "sol", limit: 4294967295
249 + t.datetime "created_at"
250 + t.datetime "updated_at"
248 251 end
249 252
250 - add_index "testcases", ["problem_id"], :name => "index_testcases_on_problem_id"
253 + add_index "testcases", ["problem_id"], name: "index_testcases_on_problem_id", using: :btree
251 254
252 - create_table "user_contest_stats", :force => true do |t|
253 - t.integer "user_id"
255 + create_table "user_contest_stats", force: :cascade do |t|
256 + t.integer "user_id", limit: 4
254 257 t.datetime "started_at"
255 - t.datetime "created_at", :null => false
256 - t.datetime "updated_at", :null => false
258 + t.datetime "created_at", null: false
259 + t.datetime "updated_at", null: false
257 260 t.boolean "forced_logout"
258 261 end
259 262
260 - create_table "users", :force => true do |t|
261 - t.string "login", :limit => 50
262 - t.string "full_name"
263 - t.string "hashed_password"
264 - t.string "salt", :limit => 5
265 - t.string "alias"
266 - t.string "email"
267 - t.integer "site_id"
268 - t.integer "country_id"
269 - t.boolean "activated", :default => false
263 + create_table "users", force: :cascade do |t|
264 + t.string "login", limit: 50
265 + t.string "full_name", limit: 255
266 + t.string "hashed_password", limit: 255
267 + t.string "salt", limit: 5
268 + t.string "alias", limit: 255
269 + t.string "email", limit: 255
270 + t.integer "site_id", limit: 4
271 + t.integer "country_id", limit: 4
272 + t.boolean "activated", default: false
270 273 t.datetime "created_at"
271 274 t.datetime "updated_at"
272 - t.boolean "enabled", :default => true
273 - t.string "remark"
274 - t.string "last_ip"
275 - t.string "section"
275 + t.boolean "enabled", default: true
276 + t.string "remark", limit: 255
277 + t.string "last_ip", limit: 255
278 + t.string "section", limit: 255
276 279 end
277 280
278 - add_index "users", ["login"], :name => "index_users_on_login", :unique => true
281 + add_index "users", ["login"], name: "index_users_on_login", unique: true, using: :btree
279 282
280 283 end
@@ -53,6 +53,7
53 53 :description => 'If the server is in contest mode and this option is true, on the log in of the admin a menu for site selections is shown.'
54 54 },
55 55
56 + #---------------------------- right --------------------------------
56 57 {
57 58 :key => 'right.user_hall_of_fame',
58 59 :value_type => 'boolean',
@@ -74,6 +75,33
74 75 :description => 'If true, any user can view submissions of every one.'
75 76 },
76 77
78 + {
79 + :key => 'right.bypass_agreement',
80 + :value_type => 'boolean',
81 + :default_value => 'true',
82 + :description => 'When false, a user must accept usage agreement before login'
83 + },
84 +
85 + {
86 + :key => 'right.heartbeat_response',
87 + :value_type => 'string',
88 + :default_value => 'OK',
89 + :description => 'Heart beat response text'
90 + },
91 +
92 + {
93 + :key => 'right.heartbeat_response_full',
94 + :value_type => 'string',
95 + :default_value => 'OK',
96 + :description => 'Heart beat response text when user got full score (set this value to the empty string to disable this feature)'
97 + },
98 +
99 + {
100 + :key => 'right.view_testcase',
101 + :value_type => 'boolean',
102 + :default_value => 'false',
103 + :description => 'When true, any user can view/download test data'
104 + },
77 105 # If Configuration['system.online_registration'] is true, the
78 106 # system allows online registration, and will use these
79 107 # information for sending confirmation emails.
@@ -55,4 +55,19
55 55 return ''
56 56 end
57 57
58 + def self.call_import_testcase(problem_name)
59 + if GraderScript.grader_control_enabled?
60 + cur_dir = `pwd`.chomp
61 + Dir.chdir(GRADER_ROOT_DIR)
62 +
63 + script_name = File.join(GRADER_ROOT_DIR, "scripts/load_testcase")
64 + cmd = "#{script_name} #{problem_name}"
65 +
66 + output = `#{cmd}`
67 +
68 + Dir.chdir(cur_dir)
69 + return "Testcase import result:\n" + output
58 70 end
71 + end
72 +
73 + end
@@ -38,6 +38,9
38 38 @log_msg << import_problem_pdf(dirname)
39 39 @log_msg << import_full_score(dirname)
40 40
41 + #import test data
42 + @log_msg << GraderScript.call_import_testcase(@problem.name)
43 +
41 44 return true
42 45 end
43 46
@@ -2,7 +2,7
2 2 require File.expand_path(File.dirname(__FILE__) + "/../../config/environment")
3 3
4 4 def clear_all_tasks
5 - Task.find(:all).each do |task|
5 + Task.all.each do |task|
6 6 task.destroy
7 7 end
8 8 end
@@ -2,13 +2,12
2 2 require File.expand_path(File.dirname(__FILE__) + "/../../config/environment")
3 3
4 4 def clear_all_tasks
5 - Task.find(:all).each do |task|
5 + Task.all.each do |task|
6 6 task.destroy
7 7 end
8 8 end
9 9
10 - puts Task.find(:all,
11 - :conditions => {:status => Task::STATUS_COMPLETE}).length
10 + puts Task.where(status: Task::STATUS_COMPLETE).length
12 11
13 12 clear_all_tasks
14 13
@@ -1,5 +1,36
1 - # Read about fixtures at http://ar.rubyonrails.org/classes/Fixtures.html
2 - one:
3 - id: 1
4 - two:
5 - id: 2
1 + Language_1:
2 + name: c
3 + pretty_name: C
4 + ext: c
5 + common_ext: c
6 +
7 + Language_2:
8 + name: cpp
9 + pretty_name: C++
10 + ext: cpp
11 + common_ext: cpp,cc
12 +
13 + Language_3:
14 + name: pas
15 + pretty_name: Pascal
16 + ext: pas
17 + common_ext: pas
18 +
19 + Language_4:
20 + name: ruby
21 + pretty_name: Ruby
22 + ext: rb
23 + common_ext: rb
24 +
25 + Language_5:
26 + name: python
27 + pretty_name: Python
28 + ext: py
29 + common_ext: py
30 +
31 + Language_6:
32 + name: java
33 + pretty_name: Java
34 + ext: java
35 + common_ext: java
36 +
@@ -13,10 +13,10
13 13 salt: <%= salt %>
14 14 activated: true
15 15
16 - mary:
17 - login: mary
18 - full_name: mary
19 - hashed_password: <%= User.encrypt("goodbye",salt) %>
16 + admin:
17 + login: admin
18 + full_name: admin
19 + hashed_password: <%= User.encrypt("admin",salt) %>
20 20 salt: <%= salt %>
21 21 roles: admin
22 22 activated: true
@@ -2,7 +2,18
2 2 require File.expand_path('../../config/environment', __FILE__)
3 3 require 'rails/test_help'
4 4
5 + #reporter for beautiful result
6 + require "minitest/reporters"
7 + Minitest::Reporters.use!
8 +
9 + module SignInHelper
10 + def sign_in_as(user,password)
11 + post login_login_path, {login: user, password: password }
12 + end
13 + end
14 +
5 15 class ActiveSupport::TestCase
16 + include SignInHelper
6 17 # Setup all fixtures in test/fixtures/*.(yml|csv) for all tests in alphabetical order.
7 18 #
8 19 # Note: You'll currently still have to declare fixtures explicitly in integration tests
deleted file
deleted file
deleted file
deleted file
deleted file
deleted file
deleted file
deleted file
deleted file
deleted file
deleted file
deleted file
deleted file
deleted file
deleted file
deleted file
deleted file
deleted file
deleted file
deleted file
deleted file
deleted file
deleted file
deleted file
deleted file
deleted file
deleted file
deleted file
deleted file
deleted file
deleted file
deleted file
deleted file
deleted file
deleted file
deleted file
deleted file
deleted file
deleted file
deleted file
deleted file
deleted file
deleted file
deleted file
deleted file
deleted file
deleted file
deleted file
deleted file
deleted file
deleted file
You need to be logged in to leave comments. Login now