Description:
merge with java
Commit status:
[Not Reviewed]
References:
merge algo
Comments:
0 Commit comments 0 Inline Comments
Unresolved TODOs:
There are no unresolved TODOs
Add another comment

r416:3378c5a77746 - - 24 files changed: 294 inserted, 86 deleted

@@ -0,0 +1,6
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
@@ -0,0 +1,3
1 + # Place all the behaviors and hooks related to the matching controller here.
2 + # All this logic will automatically be available in application.js.
3 + # You can use CoffeeScript in this file: http://jashkenas.github.com/coffee-script/
@@ -0,0 +1,3
1 + // Place all the styles related to the report controller here.
2 + // They will automatically be included in application.css.
3 + // You can use Sass (SCSS) here: http://sass-lang.com/
@@ -0,0 +1,2
1 + module ReportHelper
2 + end
@@ -0,0 +1,3
1 + class Login < ActiveRecord::Base
2 + attr_accessible :ip_address, :logged_in_at, :user_id
3 + end
@@ -0,0 +1,23
1 +
2 + = form_tag({session: :url }) do
3 + .submitbox
4 + %table
5 + %tr
6 + %td{colspan: 6, style: 'font-weight: bold'}= title
7 + %tr
8 + %td{style: 'width: 120px; font-weight: bold'}= param_text
9 + %td{align: 'right'} since:
10 + %td= text_field_tag 'since_datetime'
11 + %tr
12 + %td
13 + %td{align: 'right'} until:
14 + %td= text_field_tag 'until_datetime'
15 + %tr
16 + %td
17 + %td
18 + %td Blank mean no condition
19 + %tr
20 + %td
21 + %td
22 + %td= submit_tag 'query'
23 +
@@ -0,0 +1,33
1 + - content_for :header do
2 + = javascript_include_tag 'new'
3 +
4 + %script{:type=>"text/javascript"}
5 + $(function () {
6 + $('#since_datetime').datetimepicker({ showButtonPanel: true, dateFormat: "yy-mm-dd", controlType: "slider"} );
7 + $('#until_datetime').datetimepicker({ showButtonPanel: true, dateFormat: "yy-mm-dd", controlType: "slider"} );
8 + });
9 +
10 +
11 + %h1 Login status
12 +
13 +
14 + =render partial: 'report_menu'
15 + =render partial: 'date_range', locals: {param_text: 'Login date range:', title: 'Query login stat in the range' }
16 +
17 + %table.info
18 + %thead
19 + %tr.info-head
20 + %th login
21 + %th full name
22 + %th login count
23 + %th earliest
24 + %th latest
25 + %tbody
26 + - @logins.each do |l|
27 + %tr{class: cycle('info-even','info-odd')}
28 + %td= l[:login]
29 + %td= l[:full_name]
30 + %td= l[:count]
31 + %td= l[:min] ? l[:min].in_time_zone.strftime('%Y-%m-%d %H:%M') : ''
32 + %td= l[:max] ? l[:max].in_time_zone.strftime('%Y-%m-%d %H:%M') : ''
33 +
@@ -0,0 +1,41
1 + - content_for :header do
2 + = javascript_include_tag 'new'
3 +
4 + %script{:type=>"text/javascript"}
5 + $(function () {
6 + $('#since_datetime').datetimepicker({ showButtonPanel: true, dateFormat: "yy-mm-dd", controlType: "slider"} );
7 + $('#until_datetime').datetimepicker({ showButtonPanel: true, dateFormat: "yy-mm-dd", controlType: "slider"} );
8 + });
9 +
10 +
11 + %h1 Login status
12 +
13 +
14 +
15 +
16 + =render partial: 'report_menu'
17 + =render partial: 'date_range', locals: {param_text: 'Submission date range:', title: 'Query submission stat in the range' }
18 +
19 + %table.info
20 + %thead
21 + %tr.info-head
22 + %th login
23 + %th full name
24 + %th total submissions
25 + %th submissions
26 + %tbody
27 + - @submissions.each do |user_id,data|
28 + %tr{class: cycle('info-even','info-odd')}
29 + %td= data[:login]
30 + %td= data[:full_name]
31 + %td= data[:count]
32 + %td
33 + - data[:sub].each do |prob_id,sub_data|
34 + = "#{sub_data[:prob_name]}: ["
35 + - st = []
36 + - sub_data[:sub_ids].each do |id|
37 + - st << link_to(id, controller: 'graders' , action: 'submission', id: id)
38 + = raw st.join ', '
39 + = ']'
40 + %br/
41 +
@@ -0,0 +1,10
1 + class CreateLogins < ActiveRecord::Migration
2 + def change
3 + create_table :logins do |t|
4 + t.string :user_id
5 + t.string :ip_address
6 +
7 + t.timestamps
8 + end
9 + end
10 + end
@@ -0,0 +1,5
1 + require 'spec_helper'
2 +
3 + describe Login do
4 + pending "add some examples to (or delete) #{__FILE__}"
5 + end
@@ -1,15 +1,15
1 source 'https://rubygems.org'
1 source 'https://rubygems.org'
2
2
3 - gem 'rails', '3.2.8'
3 + gem 'rails', '3.2.19'
4
4
5 # Bundle edge Rails instead:
5 # Bundle edge Rails instead:
6 # gem 'rails', :git => 'git://github.com/rails/rails.git'
6 # gem 'rails', :git => 'git://github.com/rails/rails.git'
7
7
8 gem 'mysql2'
8 gem 'mysql2'
9
9
10 # Gems used only for assets and not required
10 # Gems used only for assets and not required
11 # in production environments by default.
11 # in production environments by default.
12 group :assets do
12 group :assets do
13 gem 'sass-rails', '~> 3.2.3'
13 gem 'sass-rails', '~> 3.2.3'
14 gem 'coffee-rails', '~> 3.2.1'
14 gem 'coffee-rails', '~> 3.2.1'
15
15
@@ -26,24 +26,30
26
26
27 # To use Jbuilder templates for JSON
27 # To use Jbuilder templates for JSON
28 # gem 'jbuilder'
28 # gem 'jbuilder'
29
29
30 # Use unicorn as the app server
30 # Use unicorn as the app server
31 # gem 'unicorn'
31 # gem 'unicorn'
32
32
33 # Deploy with Capistrano
33 # Deploy with Capistrano
34 # gem 'capistrano'
34 # gem 'capistrano'
35
35
36 # To use debugger
36 # To use debugger
37 # gem 'debugger'
37 # gem 'debugger'
38 + #
39 +
40 + gem 'jquery-rails'
41 + gem 'jquery-ui-sass-rails'
42 + gem 'jquery-timepicker-addon-rails'
43 +
38
44
39 gem "haml"
45 gem "haml"
40 gem "mail"
46 gem "mail"
41 gem "rdiscount"
47 gem "rdiscount"
42 gem "test-unit"
48 gem "test-unit"
43 gem 'will_paginate', '~> 3.0.0'
49 gem 'will_paginate', '~> 3.0.0'
44 gem 'dynamic_form'
50 gem 'dynamic_form'
45 gem 'in_place_editing'
51 gem 'in_place_editing'
46 gem 'verification', :git => 'git://github.com/sikachu/verification.git'
52 gem 'verification', :git => 'git://github.com/sikachu/verification.git'
47
53
48 group :test, :development do
54 group :test, :development do
49 gem "rspec-rails", "~> 2.0"
55 gem "rspec-rails", "~> 2.0"
@@ -1,147 +1,166
1 GIT
1 GIT
2 remote: git://github.com/sikachu/verification.git
2 remote: git://github.com/sikachu/verification.git
3 - revision: 344ad2535da3dc9671872628ff9c79d6f59af9da
3 + revision: 76eaf51b13276ecae54bd9cd115832595d2ff56d
4 specs:
4 specs:
5 verification (1.0.3)
5 verification (1.0.3)
6 - actionpack (>= 3.0.0, < 3.3.0)
6 + actionpack (>= 3.0.0, < 5.0)
7 - activesupport (>= 3.0.0, < 3.3.0)
7 + activesupport (>= 3.0.0, < 5.0)
8
8
9 GEM
9 GEM
10 remote: https://rubygems.org/
10 remote: https://rubygems.org/
11 specs:
11 specs:
12 - actionmailer (3.2.8)
12 + actionmailer (3.2.19)
13 - actionpack (= 3.2.8)
13 + actionpack (= 3.2.19)
14 - mail (~> 2.4.4)
14 + mail (~> 2.5.4)
15 - actionpack (3.2.8)
15 + actionpack (3.2.19)
16 - activemodel (= 3.2.8)
16 + activemodel (= 3.2.19)
17 - activesupport (= 3.2.8)
17 + activesupport (= 3.2.19)
18 builder (~> 3.0.0)
18 builder (~> 3.0.0)
19 erubis (~> 2.7.0)
19 erubis (~> 2.7.0)
20 journey (~> 1.0.4)
20 journey (~> 1.0.4)
21 - rack (~> 1.4.0)
21 + rack (~> 1.4.5)
22 rack-cache (~> 1.2)
22 rack-cache (~> 1.2)
23 rack-test (~> 0.6.1)
23 rack-test (~> 0.6.1)
24 - sprockets (~> 2.1.3)
24 + sprockets (~> 2.2.1)
25 - activemodel (3.2.8)
25 + activemodel (3.2.19)
26 - activesupport (= 3.2.8)
26 + activesupport (= 3.2.19)
27 builder (~> 3.0.0)
27 builder (~> 3.0.0)
28 - activerecord (3.2.8)
28 + activerecord (3.2.19)
29 - activemodel (= 3.2.8)
29 + activemodel (= 3.2.19)
30 - activesupport (= 3.2.8)
30 + activesupport (= 3.2.19)
31 arel (~> 3.0.2)
31 arel (~> 3.0.2)
32 tzinfo (~> 0.3.29)
32 tzinfo (~> 0.3.29)
33 - activeresource (3.2.8)
33 + activeresource (3.2.19)
34 - activemodel (= 3.2.8)
34 + activemodel (= 3.2.19)
35 - activesupport (= 3.2.8)
35 + activesupport (= 3.2.19)
36 - activesupport (3.2.8)
36 + activesupport (3.2.19)
37 - i18n (~> 0.6)
37 + i18n (~> 0.6, >= 0.6.4)
38 multi_json (~> 1.0)
38 multi_json (~> 1.0)
39 - arel (3.0.2)
39 + arel (3.0.3)
40 - builder (3.0.3)
40 + builder (3.0.4)
41 coffee-rails (3.2.2)
41 coffee-rails (3.2.2)
42 coffee-script (>= 2.2.0)
42 coffee-script (>= 2.2.0)
43 railties (~> 3.2.0)
43 railties (~> 3.2.0)
44 - coffee-script (2.2.0)
44 + coffee-script (2.3.0)
45 coffee-script-source
45 coffee-script-source
46 execjs
46 execjs
47 - coffee-script-source (1.3.3)
47 + coffee-script-source (1.7.1)
48 - diff-lcs (1.1.3)
48 + diff-lcs (1.2.5)
49 dynamic_form (1.1.4)
49 dynamic_form (1.1.4)
50 erubis (2.7.0)
50 erubis (2.7.0)
51 - execjs (1.4.0)
51 + execjs (2.2.1)
52 - multi_json (~> 1.0)
52 + haml (4.0.5)
53 - haml (3.1.7)
53 + tilt
54 - hike (1.2.1)
54 + hike (1.2.3)
55 - i18n (0.6.1)
55 + i18n (0.6.11)
56 in_place_editing (1.2.0)
56 in_place_editing (1.2.0)
57 journey (1.0.4)
57 journey (1.0.4)
58 - json (1.7.5)
58 + jquery-rails (3.1.1)
59 - mail (2.4.4)
59 + railties (>= 3.0, < 5.0)
60 - i18n (>= 0.4.0)
60 + thor (>= 0.14, < 2.0)
61 + jquery-timepicker-addon-rails (1.4.1)
62 + railties (>= 3.1)
63 + jquery-ui-rails (4.0.3)
64 + jquery-rails
65 + railties (>= 3.1.0)
66 + jquery-ui-sass-rails (4.0.3.0)
67 + jquery-rails
68 + jquery-ui-rails (= 4.0.3)
69 + railties (>= 3.1.0)
70 + json (1.8.1)
71 + mail (2.5.4)
61 mime-types (~> 1.16)
72 mime-types (~> 1.16)
62 treetop (~> 1.4.8)
73 treetop (~> 1.4.8)
63 - mime-types (1.19)
74 + mime-types (1.25.1)
64 - multi_json (1.3.6)
75 + multi_json (1.10.1)
65 - mysql2 (0.3.11)
76 + mysql2 (0.3.16)
66 - polyglot (0.3.3)
77 + polyglot (0.3.5)
78 + power_assert (0.1.3)
67 prototype-rails (3.2.1)
79 prototype-rails (3.2.1)
68 rails (~> 3.2)
80 rails (~> 3.2)
69 - rack (1.4.1)
81 + rack (1.4.5)
70 rack-cache (1.2)
82 rack-cache (1.2)
71 rack (>= 0.4)
83 rack (>= 0.4)
72 - rack-ssl (1.3.2)
84 + rack-ssl (1.3.4)
73 rack
85 rack
74 rack-test (0.6.2)
86 rack-test (0.6.2)
75 rack (>= 1.0)
87 rack (>= 1.0)
76 - rails (3.2.8)
88 + rails (3.2.19)
77 - actionmailer (= 3.2.8)
89 + actionmailer (= 3.2.19)
78 - actionpack (= 3.2.8)
90 + actionpack (= 3.2.19)
79 - activerecord (= 3.2.8)
91 + activerecord (= 3.2.19)
80 - activeresource (= 3.2.8)
92 + activeresource (= 3.2.19)
81 - activesupport (= 3.2.8)
93 + activesupport (= 3.2.19)
82 bundler (~> 1.0)
94 bundler (~> 1.0)
83 - railties (= 3.2.8)
95 + railties (= 3.2.19)
84 - railties (3.2.8)
96 + railties (3.2.19)
85 - actionpack (= 3.2.8)
97 + actionpack (= 3.2.19)
86 - activesupport (= 3.2.8)
98 + activesupport (= 3.2.19)
87 rack-ssl (~> 1.3.2)
99 rack-ssl (~> 1.3.2)
88 rake (>= 0.8.7)
100 rake (>= 0.8.7)
89 rdoc (~> 3.4)
101 rdoc (~> 3.4)
90 thor (>= 0.14.6, < 2.0)
102 thor (>= 0.14.6, < 2.0)
91 - rake (0.9.2.2)
103 + rake (10.3.2)
92 - rdiscount (1.6.8)
104 + rdiscount (2.1.7.1)
93 - rdoc (3.12)
105 + rdoc (3.12.2)
94 json (~> 1.4)
106 json (~> 1.4)
95 - rspec (2.11.0)
107 + rspec-collection_matchers (1.0.0)
96 - rspec-core (~> 2.11.0)
108 + rspec-expectations (>= 2.99.0.beta1)
97 - rspec-expectations (~> 2.11.0)
109 + rspec-core (2.99.2)
98 - rspec-mocks (~> 2.11.0)
110 + rspec-expectations (2.99.2)
99 - rspec-core (2.11.1)
111 + diff-lcs (>= 1.1.3, < 2.0)
100 - rspec-expectations (2.11.3)
112 + rspec-mocks (2.99.2)
101 - diff-lcs (~> 1.1.3)
113 + rspec-rails (2.99.0)
102 - rspec-mocks (2.11.3)
103 - rspec-rails (2.11.0)
104 actionpack (>= 3.0)
114 actionpack (>= 3.0)
115 + activemodel (>= 3.0)
105 activesupport (>= 3.0)
116 activesupport (>= 3.0)
106 railties (>= 3.0)
117 railties (>= 3.0)
107 - rspec (~> 2.11.0)
118 + rspec-collection_matchers
108 - sass (3.2.1)
119 + rspec-core (~> 2.99.0)
109 - sass-rails (3.2.5)
120 + rspec-expectations (~> 2.99.0)
121 + rspec-mocks (~> 2.99.0)
122 + sass (3.4.1)
123 + sass-rails (3.2.6)
110 railties (~> 3.2.0)
124 railties (~> 3.2.0)
111 sass (>= 3.1.10)
125 sass (>= 3.1.10)
112 tilt (~> 1.3)
126 tilt (~> 1.3)
113 - sprockets (2.1.3)
127 + sprockets (2.2.2)
114 hike (~> 1.2)
128 hike (~> 1.2)
129 + multi_json (~> 1.0)
115 rack (~> 1.0)
130 rack (~> 1.0)
116 tilt (~> 1.1, != 1.3.0)
131 tilt (~> 1.1, != 1.3.0)
117 - test-unit (2.5.2)
132 + test-unit (3.0.1)
118 - thor (0.16.0)
133 + power_assert
119 - tilt (1.3.3)
134 + thor (0.19.1)
120 - treetop (1.4.10)
135 + tilt (1.4.1)
136 + treetop (1.4.15)
121 polyglot
137 polyglot
122 polyglot (>= 0.3.1)
138 polyglot (>= 0.3.1)
123 - tzinfo (0.3.33)
139 + tzinfo (0.3.41)
124 - uglifier (1.3.0)
140 + uglifier (2.5.3)
125 execjs (>= 0.3.0)
141 execjs (>= 0.3.0)
126 - multi_json (~> 1.0, >= 1.0.2)
142 + json (>= 1.8.0)
127 - will_paginate (3.0.3)
143 + will_paginate (3.0.7)
128
144
129 PLATFORMS
145 PLATFORMS
130 ruby
146 ruby
131
147
132 DEPENDENCIES
148 DEPENDENCIES
133 coffee-rails (~> 3.2.1)
149 coffee-rails (~> 3.2.1)
134 dynamic_form
150 dynamic_form
135 haml
151 haml
136 in_place_editing
152 in_place_editing
153 + jquery-rails
154 + jquery-timepicker-addon-rails
155 + jquery-ui-sass-rails
137 mail
156 mail
138 mysql2
157 mysql2
139 prototype-rails
158 prototype-rails
140 - rails (= 3.2.8)
159 + rails (= 3.2.19)
141 rdiscount
160 rdiscount
142 rspec-rails (~> 2.0)
161 rspec-rails (~> 2.0)
143 sass-rails (~> 3.2.3)
162 sass-rails (~> 3.2.3)
144 test-unit
163 test-unit
145 uglifier (>= 1.0.3)
164 uglifier (>= 1.0.3)
146 verification!
165 verification!
147 will_paginate (~> 3.0.0)
166 will_paginate (~> 3.0.0)
@@ -1,12 +1,20
1 +
2 + @import jquery.ui.core
3 + @import jquery.ui.theme
4 + @import jquery.ui.datepicker
5 + @import jquery.ui.slider
6 + @import jquery-ui-timepicker-addon
7 +
8 +
1 body
9 body
2 background: white image-url("topbg.jpg") repeat-x top center
10 background: white image-url("topbg.jpg") repeat-x top center
3 font-size: 13px
11 font-size: 13px
4 font-family: Tahoma, "sans-serif"
12 font-family: Tahoma, "sans-serif"
5 margin: 10px
13 margin: 10px
6 padding: 10px
14 padding: 10px
7
15
8
16
9 input
17 input
10 font-family: Tahoma, "sans-serif"
18 font-family: Tahoma, "sans-serif"
11
19
12
20
@@ -281,13 +289,13
281 line-height: 2em
289 line-height: 2em
282
290
283 &.registration-desc, &.test-desc
291 &.registration-desc, &.test-desc
284 border: 1px dotted gray
292 border: 1px dotted gray
285 background: #f5f5f5
293 background: #f5f5f5
286 padding: 5px
294 padding: 5px
287 margin: 10px 0
295 margin: 10px 0
288 font-size: 12px
296 font-size: 12px
289 line-height: 1.5em
297 line-height: 1.5em
290
298
291 h2.contest-title
299 h2.contest-title
292 margin-top: 5px
300 margin-top: 5px
293 - margin-bottom: 5px No newline at end of file
301 + margin-bottom: 5px
@@ -13,24 +13,27
13
13
14 # clear forced logout flag for multicontests contest change
14 # clear forced logout flag for multicontests contest change
15 if GraderConfiguration.multicontests?
15 if GraderConfiguration.multicontests?
16 contest_stat = user.contest_stat
16 contest_stat = user.contest_stat
17 if contest_stat.respond_to? :forced_logout
17 if contest_stat.respond_to? :forced_logout
18 if contest_stat.forced_logout
18 if contest_stat.forced_logout
19 contest_stat.forced_logout = false
19 contest_stat.forced_logout = false
20 contest_stat.save
20 contest_stat.save
21 end
21 end
22 end
22 end
23 end
23 end
24
24
25 + #save login information
26 + Login.create(user_id: user.id, ip_address: request.remote_ip)
27 +
25 redirect_to :controller => 'main', :action => 'list'
28 redirect_to :controller => 'main', :action => 'list'
26 else
29 else
27 flash[:notice] = 'Wrong password'
30 flash[:notice] = 'Wrong password'
28 redirect_to :controller => 'main', :action => 'login'
31 redirect_to :controller => 'main', :action => 'login'
29 end
32 end
30 end
33 end
31
34
32 def site_login
35 def site_login
33 begin
36 begin
34 site = Site.find(params[:login][:site_id])
37 site = Site.find(params[:login][:site_id])
35 rescue ActiveRecord::RecordNotFound
38 rescue ActiveRecord::RecordNotFound
36 site = nil
39 site = nil
@@ -4,24 +4,25
4 def user_header
4 def user_header
5 menu_items = ''
5 menu_items = ''
6 user = User.find(session[:user_id])
6 user = User.find(session[:user_id])
7
7
8 if (user!=nil) and (session[:admin])
8 if (user!=nil) and (session[:admin])
9 # admin menu
9 # admin menu
10 menu_items << "<b>Administrative task:</b> "
10 menu_items << "<b>Administrative task:</b> "
11 append_to menu_items, '[Announcements]', 'announcements', 'index'
11 append_to menu_items, '[Announcements]', 'announcements', 'index'
12 append_to menu_items, '[Msg console]', 'messages', 'console'
12 append_to menu_items, '[Msg console]', 'messages', 'console'
13 append_to menu_items, '[Problems]', 'problems', 'index'
13 append_to menu_items, '[Problems]', 'problems', 'index'
14 append_to menu_items, '[Users]', 'user_admin', 'index'
14 append_to menu_items, '[Users]', 'user_admin', 'index'
15 append_to menu_items, '[Results]', 'user_admin', 'user_stat'
15 append_to menu_items, '[Results]', 'user_admin', 'user_stat'
16 + append_to menu_items, '[Report]', 'report', 'login_stat'
16 append_to menu_items, '[Graders]', 'graders', 'list'
17 append_to menu_items, '[Graders]', 'graders', 'list'
17 append_to menu_items, '[Contests]', 'contest_management', 'index'
18 append_to menu_items, '[Contests]', 'contest_management', 'index'
18 append_to menu_items, '[Sites]', 'sites', 'index'
19 append_to menu_items, '[Sites]', 'sites', 'index'
19 append_to menu_items, '[System config]', 'configurations', 'index'
20 append_to menu_items, '[System config]', 'configurations', 'index'
20 menu_items << "<br/>"
21 menu_items << "<br/>"
21 end
22 end
22
23
23 # main page
24 # main page
24 append_to menu_items, "[#{I18n.t 'menu.main'}]", 'main', 'list'
25 append_to menu_items, "[#{I18n.t 'menu.main'}]", 'main', 'list'
25 append_to menu_items, "[#{I18n.t 'menu.messages'}]", 'messages', 'list'
26 append_to menu_items, "[#{I18n.t 'menu.messages'}]", 'messages', 'list'
26
27
27 if (user!=nil) and (GraderConfiguration.show_tasks_to?(user))
28 if (user!=nil) and (GraderConfiguration.show_tasks_to?(user))
@@ -5,25 +5,25
5 has_many :test_pairs, :dependent => :delete_all
5 has_many :test_pairs, :dependent => :delete_all
6
6
7 validates_presence_of :name
7 validates_presence_of :name
8 validates_format_of :name, :with => /^\w+$/
8 validates_format_of :name, :with => /^\w+$/
9 validates_presence_of :full_name
9 validates_presence_of :full_name
10
10
11 scope :available, :conditions => {:available => true}
11 scope :available, :conditions => {:available => true}
12
12
13 DEFAULT_TIME_LIMIT = 1
13 DEFAULT_TIME_LIMIT = 1
14 DEFAULT_MEMORY_LIMIT = 32
14 DEFAULT_MEMORY_LIMIT = 32
15
15
16 def self.find_available_problems
16 def self.find_available_problems
17 - Problem.available.all(:order => "date_added DESC")
17 + Problem.available.all(:order => "date_added DESC, name ASC")
18 end
18 end
19
19
20 def self.create_from_import_form_params(params, old_problem=nil)
20 def self.create_from_import_form_params(params, old_problem=nil)
21 org_problem = old_problem || Problem.new
21 org_problem = old_problem || Problem.new
22 import_params, problem = Problem.extract_params_and_check(params,
22 import_params, problem = Problem.extract_params_and_check(params,
23 org_problem)
23 org_problem)
24
24
25 if !problem.errors.empty?
25 if !problem.errors.empty?
26 return problem, 'Error importing'
26 return problem, 'Error importing'
27 end
27 end
28
28
29 problem.full_score = 100
29 problem.full_score = 100
@@ -34,24 +34,25
34
34
35 if not problem.save
35 if not problem.save
36 return problem, 'Error importing'
36 return problem, 'Error importing'
37 end
37 end
38
38
39 import_to_db = params.has_key? :import_to_db
39 import_to_db = params.has_key? :import_to_db
40
40
41 importer = TestdataImporter.new(problem)
41 importer = TestdataImporter.new(problem)
42
42
43 if not importer.import_from_file(import_params[:file],
43 if not importer.import_from_file(import_params[:file],
44 import_params[:time_limit],
44 import_params[:time_limit],
45 import_params[:memory_limit],
45 import_params[:memory_limit],
46 + import_params[:checker_name],
46 import_to_db)
47 import_to_db)
47 problem.errors.add_to_base('Import error.')
48 problem.errors.add_to_base('Import error.')
48 end
49 end
49
50
50 return problem, importer.log_msg
51 return problem, importer.log_msg
51 end
52 end
52
53
53 def self.download_file_basedir
54 def self.download_file_basedir
54 return "#{Rails.root}/data/tasks"
55 return "#{Rails.root}/data/tasks"
55 end
56 end
56
57
57 protected
58 protected
@@ -81,34 +82,40
81 end
82 end
82
83
83 if memory_limit==0 and params[:memory_limit]!='0'
84 if memory_limit==0 and params[:memory_limit]!='0'
84 problem.errors.add_to_base('Memory limit format errors.')
85 problem.errors.add_to_base('Memory limit format errors.')
85 elsif memory_limit<=0 or memory_limit >512
86 elsif memory_limit<=0 or memory_limit >512
86 problem.errors.add_to_base('Memory limit out of range.')
87 problem.errors.add_to_base('Memory limit out of range.')
87 end
88 end
88
89
89 if params[:file]==nil or params[:file]==''
90 if params[:file]==nil or params[:file]==''
90 problem.errors.add_to_base('No testdata file.')
91 problem.errors.add_to_base('No testdata file.')
91 end
92 end
92
93
94 + checker_name = 'text'
95 + if ['text','float'].include? params[:checker]
96 + checker_name = params[:checker]
97 + end
98 +
93 file = params[:file]
99 file = params[:file]
94
100
95 if !problem.errors.empty?
101 if !problem.errors.empty?
96 return nil, problem
102 return nil, problem
97 end
103 end
98
104
99 problem.name = params[:name]
105 problem.name = params[:name]
100 if params[:full_name]!=''
106 if params[:full_name]!=''
101 problem.full_name = params[:full_name]
107 problem.full_name = params[:full_name]
102 else
108 else
103 problem.full_name = params[:name]
109 problem.full_name = params[:name]
104 end
110 end
105
111
106 return [{
112 return [{
107 :time_limit => time_limit,
113 :time_limit => time_limit,
108 :memory_limit => memory_limit,
114 :memory_limit => memory_limit,
109 - :file => file
115 + :file => file,
116 + :checker_name => checker_name
110 },
117 },
111 problem]
118 problem]
112 end
119 end
113
120
114 end
121 end
@@ -1,14 +1,16
1 require 'digest/sha1'
1 require 'digest/sha1'
2 require 'net/pop'
2 require 'net/pop'
3 + require 'net/https'
4 + require 'net/http'
3 require 'json'
5 require 'json'
4
6
5 class User < ActiveRecord::Base
7 class User < ActiveRecord::Base
6
8
7 has_and_belongs_to_many :roles
9 has_and_belongs_to_many :roles
8
10
9 has_many :test_requests, :order => "submitted_at DESC"
11 has_many :test_requests, :order => "submitted_at DESC"
10
12
11 has_many :messages,
13 has_many :messages,
12 :class_name => "Message",
14 :class_name => "Message",
13 :foreign_key => "sender_id",
15 :foreign_key => "sender_id",
14 :order => 'created_at DESC'
16 :order => 'created_at DESC'
@@ -72,25 +74,25
72 end
74 end
73 end
75 end
74 end
76 end
75
77
76 def authenticated?(password)
78 def authenticated?(password)
77 if self.activated
79 if self.activated
78 hashed_password == User.encrypt(password,self.salt)
80 hashed_password == User.encrypt(password,self.salt)
79 else
81 else
80 false
82 false
81 end
83 end
82 end
84 end
83
85
84 - def authenticated_by_pop3?(password)
86 + def authenticated_by_pop3?(password)
85 Net::POP3.enable_ssl
87 Net::POP3.enable_ssl
86 pop = Net::POP3.new('pops.it.chula.ac.th')
88 pop = Net::POP3.new('pops.it.chula.ac.th')
87 authen = true
89 authen = true
88 begin
90 begin
89 pop.start(login, password)
91 pop.start(login, password)
90 pop.finish
92 pop.finish
91 return true
93 return true
92 rescue
94 rescue
93 return false
95 return false
94 end
96 end
95 end
97 end
96
98
@@ -98,26 +100,33
98 url = URI.parse('https://www.cas.chula.ac.th/cas/api/?q=studentAuthenticate')
100 url = URI.parse('https://www.cas.chula.ac.th/cas/api/?q=studentAuthenticate')
99 appid = '41508763e340d5858c00f8c1a0f5a2bb'
101 appid = '41508763e340d5858c00f8c1a0f5a2bb'
100 appsecret ='d9cbb5863091dbe186fded85722a1e31'
102 appsecret ='d9cbb5863091dbe186fded85722a1e31'
101 post_args = {
103 post_args = {
102 'appid' => appid,
104 'appid' => appid,
103 'appsecret' => appsecret,
105 'appsecret' => appsecret,
104 'username' => login,
106 'username' => login,
105 'password' => password
107 'password' => password
106 }
108 }
107
109
108 #simple call
110 #simple call
109 begin
111 begin
110 - resp = Net::HTTP.post_form(url, post_args)
112 + http = Net::HTTP.new('www.cas.chula.ac.th', 443)
111 - result = JSON.parse resp.body
113 + http.use_ssl = true
114 + result = [ ]
115 + http.start do |http|
116 + req = Net::HTTP::Post.new('/cas/api/?q=studentAuthenticate')
117 + param = "appid=#{appid}&appsecret=#{appsecret}&username=#{login}&password=#{password}"
118 + resp = http.request(req,param)
119 + result = JSON.parse resp.body
120 + end
112 return true if result["type"] == "beanStudent"
121 return true if result["type"] == "beanStudent"
113 rescue
122 rescue
114 return false
123 return false
115 end
124 end
116 return false
125 return false
117 end
126 end
118
127
119 def admin?
128 def admin?
120 self.roles.detect {|r| r.name == 'admin' }
129 self.roles.detect {|r| r.name == 'admin' }
121 end
130 end
122
131
123 def email_for_editing
132 def email_for_editing
@@ -1,20 +1,22
1 <!DOCTYPE html>
1 <!DOCTYPE html>
2 <html>
2 <html>
3 <head>
3 <head>
4 <title><%= GraderConfiguration['contest.name'] %></title>
4 <title><%= GraderConfiguration['contest.name'] %></title>
5 <%= stylesheet_link_tag "application", :media => "all" %>
5 <%= stylesheet_link_tag "application", :media => "all" %>
6 <%= javascript_include_tag "application" %>
6 <%= javascript_include_tag "application" %>
7 <%= csrf_meta_tags %>
7 <%= csrf_meta_tags %>
8 + <%= content_for :header %>
8 <%= yield :head %>
9 <%= yield :head %>
10 +
9 </head>
11 </head>
10 <body>
12 <body>
11
13
12 <div class="userbar">
14 <div class="userbar">
13 <%= user_header %>
15 <%= user_header %>
14 </div>
16 </div>
15
17
16 <%= content_tag(:p,flash[:notice],:style => "color:green") if flash[:notice]!=nil %>
18 <%= content_tag(:p,flash[:notice],:style => "color:green") if flash[:notice]!=nil %>
17
19
18 <%= yield %>
20 <%= yield %>
19
21
20 </body>
22 </body>
@@ -1,18 +1,18
1 <tr class="info-<%= (problem_counter%2==0) ? "even" : "odd" %>">
1 <tr class="info-<%= (problem_counter%2==0) ? "even" : "odd" %>">
2 <td>
2 <td>
3 <%= "#{problem_counter+1}" %>
3 <%= "#{problem_counter+1}" %>
4 </td>
4 </td>
5 <td>
5 <td>
6 - <%= "#{problem.full_name} (#{problem.name})" %>
6 + <%= "(#{problem.name}) #{problem.full_name}" %>
7 <%= link_to_description_if_any "[#{t 'main.problem_desc'}]", problem %>
7 <%= link_to_description_if_any "[#{t 'main.problem_desc'}]", problem %>
8 </td>
8 </td>
9 <td align="center">
9 <td align="center">
10 <%= @prob_submissions[problem.id][:count] %>
10 <%= @prob_submissions[problem.id][:count] %>
11 </td>
11 </td>
12 <td>
12 <td>
13 <%= render :partial => 'submission_short',
13 <%= render :partial => 'submission_short',
14 :locals => {
14 :locals => {
15 :submission => @prob_submissions[problem.id][:submission],
15 :submission => @prob_submissions[problem.id][:submission],
16 :problem_name => problem.name }%>
16 :problem_name => problem.name }%>
17 </td>
17 </td>
18 </tr>
18 </tr>
@@ -23,24 +23,37
23 %td Testdata file:
23 %td Testdata file:
24 %td= file_field_tag 'file'
24 %td= file_field_tag 'file'
25 %tr
25 %tr
26 %td
26 %td
27 %td
27 %td
28 %span{:class => 'help'}
28 %span{:class => 'help'}
29 In .zip, .tgz, tar.gz, .tar format.
29 In .zip, .tgz, tar.gz, .tar format.
30 It should includes inputs (e.g., 1.in, 2a.in, 2b.in)
30 It should includes inputs (e.g., 1.in, 2a.in, 2b.in)
31 and solutions (e.g., 1.sol, 2a.sol, 2b.sol).
31 and solutions (e.g., 1.sol, 2a.sol, 2b.sol).
32 %br/
32 %br/
33 You may put task description in *.html for raw html
33 You may put task description in *.html for raw html
34 and *.md or *.markdown for markdown.
34 and *.md or *.markdown for markdown.
35 + %br/
36 + You may also put a pdf file for the task description
37 + %tr
38 + %td Checker:
39 + %td= select_tag 'checker', options_for_select([['Text checker','text'],['Float checker','float']], 'text')
40 + %tr
41 + %td
42 + %td
43 + %span{:class => 'help'}
44 + "Text" checker checks if the text (including numbers) is the same, ignoring any whitespace
45 + %br/
46 + "Float" checker checks if all numbers is within EPSILON error using formula |a-b| < EPSILON * max(|a|,|b|)
47 +
35 - if @allow_test_pair_import
48 - if @allow_test_pair_import
36 %tr
49 %tr
37 %td
50 %td
38 %td
51 %td
39 = check_box_tag 'import_to_db'
52 = check_box_tag 'import_to_db'
40 Import test data to database (for a test-pair task)
53 Import test data to database (for a test-pair task)
41 %tr
54 %tr
42 %td Time limit:
55 %td Time limit:
43 %td
56 %td
44 = text_field_tag 'time_limit'
57 = text_field_tag 'time_limit'
45 %span{:class => 'help'} In seconds. Leave blank to use 1 sec.
58 %span{:class => 'help'} In seconds. Leave blank to use 1 sec.
46 %tr
59 %tr
@@ -1,13 +1,15
1 CafeGrader::Application.routes.draw do
1 CafeGrader::Application.routes.draw do
2 + get "report/login"
3 +
2 resources :contests
4 resources :contests
3
5
4 resources :announcements
6 resources :announcements
5 resources :sites
7 resources :sites
6
8
7 # The priority is based upon order of creation:
9 # The priority is based upon order of creation:
8 # first created -> highest priority.
10 # first created -> highest priority.
9
11
10 # Sample of regular route:
12 # Sample of regular route:
11 # match 'products/:id' => 'catalog#view'
13 # match 'products/:id' => 'catalog#view'
12 # Keep in mind you can assign values other than :controller and :action
14 # Keep in mind you can assign values other than :controller and :action
13
15
@@ -2,25 +2,25
2 # This file is auto-generated from the current state of the database. Instead
2 # This file is auto-generated from the current state of the database. Instead
3 # of editing this file, please use the migrations feature of Active Record to
3 # of editing this file, please use the migrations feature of Active Record to
4 # incrementally modify your database, and then regenerate this schema definition.
4 # incrementally modify your database, and then regenerate this schema definition.
5 #
5 #
6 # Note that this schema.rb definition is the authoritative source for your
6 # Note that this schema.rb definition is the authoritative source for your
7 # database schema. If you need to create the application database on another
7 # database schema. If you need to create the application database on another
8 # system, you should be using db:schema:load, not running all the migrations
8 # system, you should be using db:schema:load, not running all the migrations
9 # from scratch. The latter is a flawed and unsustainable approach (the more migrations
9 # from scratch. The latter is a flawed and unsustainable approach (the more migrations
10 # you'll amass, the slower it'll run and the greater likelihood for issues).
10 # you'll amass, the slower it'll run and the greater likelihood for issues).
11 #
11 #
12 # It's strongly recommended to check this file into your version control system.
12 # It's strongly recommended to check this file into your version control system.
13
13
14 - ActiveRecord::Schema.define(:version => 20140823031747) do
14 + ActiveRecord::Schema.define(:version => 20140826095949) do
15
15
16 create_table "announcements", :force => true do |t|
16 create_table "announcements", :force => true do |t|
17 t.string "author"
17 t.string "author"
18 t.text "body"
18 t.text "body"
19 t.boolean "published"
19 t.boolean "published"
20 t.datetime "created_at", :null => false
20 t.datetime "created_at", :null => false
21 t.datetime "updated_at", :null => false
21 t.datetime "updated_at", :null => false
22 t.boolean "frontpage", :default => false
22 t.boolean "frontpage", :default => false
23 t.boolean "contest_only", :default => false
23 t.boolean "contest_only", :default => false
24 t.string "title"
24 t.string "title"
25 t.string "notes"
25 t.string "notes"
26 end
26 end
@@ -77,24 +77,31
77 t.boolean "terminated"
77 t.boolean "terminated"
78 end
78 end
79
79
80 add_index "grader_processes", ["host", "pid"], :name => "index_grader_processes_on_ip_and_pid"
80 add_index "grader_processes", ["host", "pid"], :name => "index_grader_processes_on_ip_and_pid"
81
81
82 create_table "languages", :force => true do |t|
82 create_table "languages", :force => true do |t|
83 t.string "name", :limit => 10
83 t.string "name", :limit => 10
84 t.string "pretty_name"
84 t.string "pretty_name"
85 t.string "ext", :limit => 10
85 t.string "ext", :limit => 10
86 t.string "common_ext"
86 t.string "common_ext"
87 end
87 end
88
88
89 + create_table "logins", :force => true do |t|
90 + t.string "user_id"
91 + t.string "ip_address"
92 + t.datetime "created_at", :null => false
93 + t.datetime "updated_at", :null => false
94 + end
95 +
89 create_table "messages", :force => true do |t|
96 create_table "messages", :force => true do |t|
90 t.integer "sender_id"
97 t.integer "sender_id"
91 t.integer "receiver_id"
98 t.integer "receiver_id"
92 t.integer "replying_message_id"
99 t.integer "replying_message_id"
93 t.text "body"
100 t.text "body"
94 t.boolean "replied"
101 t.boolean "replied"
95 t.datetime "created_at", :null => false
102 t.datetime "created_at", :null => false
96 t.datetime "updated_at", :null => false
103 t.datetime "updated_at", :null => false
97 end
104 end
98
105
99 create_table "problems", :force => true do |t|
106 create_table "problems", :force => true do |t|
100 t.string "name", :limit => 30
107 t.string "name", :limit => 30
@@ -41,18 +41,18
41 if GraderScript.grader_control_enabled?
41 if GraderScript.grader_control_enabled?
42 cur_dir = `pwd`.chomp
42 cur_dir = `pwd`.chomp
43 Dir.chdir(GRADER_ROOT_DIR)
43 Dir.chdir(GRADER_ROOT_DIR)
44
44
45 script_name = File.join(GRADER_ROOT_DIR, "scripts/import_problem")
45 script_name = File.join(GRADER_ROOT_DIR, "scripts/import_problem")
46 cmd = "#{script_name} #{problem_name} #{problem_dir} #{checker_name}" +
46 cmd = "#{script_name} #{problem_name} #{problem_dir} #{checker_name}" +
47 " -t #{time_limit} -m #{memory_limit}"
47 " -t #{time_limit} -m #{memory_limit}"
48
48
49 output = `#{cmd}`
49 output = `#{cmd}`
50
50
51 Dir.chdir(cur_dir)
51 Dir.chdir(cur_dir)
52
52
53 - return output
53 + return "import CMD: #{cmd}\n" + output
54 end
54 end
55 return ''
55 return ''
56 end
56 end
57
57
58 end
58 end
@@ -2,33 +2,35
2
2
3 class TestdataImporter
3 class TestdataImporter
4
4
5 attr :log_msg
5 attr :log_msg
6
6
7 def initialize(problem)
7 def initialize(problem)
8 @problem = problem
8 @problem = problem
9 end
9 end
10
10
11 def import_from_file(tempfile,
11 def import_from_file(tempfile,
12 time_limit,
12 time_limit,
13 memory_limit,
13 memory_limit,
14 + checker_name='text',
14 import_to_db=false)
15 import_to_db=false)
15
16
16 dirname = extract(tempfile)
17 dirname = extract(tempfile)
17 return false if not dirname
18 return false if not dirname
18 if not import_to_db
19 if not import_to_db
19 @log_msg = GraderScript.call_import_problem(@problem.name,
20 @log_msg = GraderScript.call_import_problem(@problem.name,
20 dirname,
21 dirname,
21 time_limit,
22 time_limit,
22 - memory_limit)
23 + memory_limit,
24 + checker_name)
23 else
25 else
24 # Import test data to test pairs.
26 # Import test data to test pairs.
25
27
26 @problem.test_pairs.clear
28 @problem.test_pairs.clear
27 if import_test_pairs(dirname)
29 if import_test_pairs(dirname)
28 test_pair_count = TestPair.count :conditions => "problem_id = #{@problem.id}"
30 test_pair_count = TestPair.count :conditions => "problem_id = #{@problem.id}"
29 @log_msg = "Importing test pair successful. (#{test_pair_count} test pairs imported)"
31 @log_msg = "Importing test pair successful. (#{test_pair_count} test pairs imported)"
30 else
32 else
31 @log_msg = "Importing test pair failed. (0 test pairs imported)"
33 @log_msg = "Importing test pair failed. (0 test pairs imported)"
32 end
34 end
33 end
35 end
34
36
You need to be logged in to leave comments. Login now