Description:
MERGED 308:HEAD from http://theory.cpe.ku.ac.th/grader/web/branches/ytopc08-2/, removed some registration info git-svn-id: http://theory.cpe.ku.ac.th/grader/web/trunk@359 6386c4cd-e34a-4fa8-8920-d93eb39b512e
Commit status:
[Not Reviewed]
References:
Comments:
0 Commit comments 0 Inline Comments
Unresolved TODOs:
There are no unresolved TODOs
Add another comment

r162:39cf7851046e - - 70 files changed: 899 inserted, 391 deleted

@@ -0,0 +1,4
1 + *~
2 + log
3 + config/environment.rb
4 + config/database.yml
@@ -0,0 +1,76
1 + # Filters added to this controller apply to all controllers in the application.
2 + # Likewise, all the methods added will be available for all controllers.
3 +
4 + class ApplicationController < ActionController::Base
5 + # Pick a unique cookie name to distinguish our session data from others'
6 + session :session_key => '_grader_session_id'
7 +
8 + SINGLE_USER_MODE_CONF_KEY = 'system.single_user_mode'
9 +
10 + def admin_authorization
11 + return false unless authenticate
12 + user = User.find(session[:user_id], :include => ['roles'])
13 + redirect_to :controller => 'main', :action => 'login' unless user.admin?
14 + end
15 +
16 + def authorization_by_roles(allowed_roles)
17 + return false unless authenticate
18 + user = User.find(session[:user_id])
19 + unless user.roles.detect { |role| allowed_roles.member?(role.name) }
20 + flash[:notice] = 'You are not authorized to view the page you requested'
21 + redirect_to :controller => 'main', :action => 'login'
22 + return false
23 + end
24 + end
25 +
26 + protected
27 +
28 + def authenticate
29 + unless session[:user_id]
30 + redirect_to :controller => 'main', :action => 'login'
31 + return false
32 + end
33 +
34 + #Configuration.reload
35 + # check if run in single user mode
36 + if (Configuration[SINGLE_USER_MODE_CONF_KEY])
37 + user = User.find(session[:user_id])
38 + if user==nil or user.login != 'root'
39 + redirect_to :controller => 'main', :action => 'login'
40 + return false
41 + end
42 + end
43 +
44 + return true
45 + end
46 +
47 + def authorization
48 + return false unless authenticate
49 + user = User.find(session[:user_id])
50 + unless user.roles.detect { |role|
51 + role.rights.detect{ |right|
52 + right.controller == self.class.controller_name and
53 + (right.action == 'all' or right.action == action_name)
54 + }
55 + }
56 + flash[:notice] = 'You are not authorized to view the page you requested'
57 + #request.env['HTTP_REFERER'] ? (redirect_to :back) : (redirect_to :controller => 'login')
58 + redirect_to :controller => 'main', :action => 'login'
59 + return false
60 + end
61 + end
62 +
63 + def verify_time_limit
64 + return true if session[:user_id]==nil
65 + user = User.find(session[:user_id], :include => :site)
66 + return true if user==nil or user.site == nil
67 + if user.site.finished?
68 + flash[:notice] = 'Error: the contest on your site is over.'
69 + redirect_to :back
70 + return false
71 + end
72 + return true
73 + end
74 +
75 + end
76 +
@@ -0,0 +1,39
1 + %script{:type => 'text/javascript'}
2 + var siteList = new Array();
3 + - @countries.each do |country|
4 + = "siteList[#{country.id}] = new Array();"
5 + - country.sites.each do |site|
6 + = "siteList[#{country.id}][#{site.id}] = \"#{site.name}\";"
7 +
8 + var allSiteList = new Array();
9 + - @site_select.each do |sel|
10 + = "allSiteList[#{sel[1]}]=\"#{sel[0]}\";"
11 +
12 + %script{:type => 'text/javascript', :src => '/javascripts/site_update.js'}
13 +
14 + %div{ :style => "border: solid 1px gray; padding: 2px; background: #f0f0f0;"}
15 + %h2 For Site Administrator.
16 +
17 + - if @default_site
18 + - form_for :login, nil, :url => {:controller => 'login', :action => 'site_login'} do |f|
19 + %b Log in for default site.
20 + = f.hidden_field :site_id, :value => @default_site.id
21 + %br/
22 + Password:
23 + = f.password_field :password
24 + = submit_tag "Site Administrator Login"
25 +
26 + - else
27 + Please select your country and site and login.
28 + - form_for :login, nil, :url => {:controller => 'login', :action => 'site_login'} do |f|
29 + Country:
30 + = select :site_country, :id, @country_select_with_all, {}, {:onchange => "updateSiteList();", :onclick => "updateSiteList();" }
31 + Site:
32 + = select :login, :site_id, @site_select
33 + %br/
34 + Password:
35 + = f.password_field :password
36 + = submit_tag "Site Administrator Login"
37 +
38 + %script{:type => 'text/javascript'}
39 + updateSiteList();
@@ -0,0 +1,118
1 + # Sample localization file for English. Add more files in this directory for other locales.
2 + # See http://github.com/svenfuchs/rails-i18n/tree/master/rails%2Flocale for starting points.
3 +
4 + en:
5 + cancel: 'Cancel'
6 +
7 + login_label: 'Login'
8 + full_name_label: 'Full name'
9 + email_label: 'E-mail'
10 + password_label: 'Password'
11 +
12 + go_ahead_to: "Go ahead to"
13 + go_back_to: "Go back to"
14 + login_page: "login page"
15 + home_page: "home page"
16 +
17 + menu:
18 + main: 'Main'
19 + messages: 'Messages'
20 + tasks: 'Tasks'
21 + submissions: 'Submissions'
22 + test: 'Test Interface'
23 + help: 'Help'
24 + settings: 'Settings'
25 + log_out: 'Log out'
26 +
27 + title_bar:
28 + current_time: "Current time is"
29 + remaining_time: "Time left: "
30 + contest_not_started: "The contest has not started."
31 +
32 + login:
33 + message: 'Please login to see the problem list'
34 + login_submit: 'Login'
35 + participation: 'Want to participate?'
36 + please: 'Please'
37 + register: 'register'
38 +
39 + main:
40 + start_soon: "The contest at your site will start soon. Please wait."
41 + specified_in_header: "Specified in header"
42 +
43 + problem_desc: "desc"
44 + submitted_at: "Submitted at"
45 + graded_at: "Graded at"
46 + score: "score: "
47 + cmp_msg: "compiler msg"
48 + src_link: "src"
49 + submissions_link: "submissions"
50 +
51 + test:
52 + title: "Test Interface"
53 + intro: "You can test your submission with your own test data on the grading environment using this test interface."
54 + disabled_at_end_announcement: "<b>Note:</b> Test interface will be disabled in the last 30 minutes of the contest time on your site."
55 +
56 + registration:
57 + title: "New user registration"
58 + successful_title: "Registration successful"
59 +
60 + login_guide: "Only a-z, A-Z, 0-9 and _. Can be at most 20 characters long"
61 + email_guide: "Please make sure that your e-mail is correct.<br/>You'll need to verify your account by email."
62 + register: "Register"
63 +
64 + email_body: "Hello {{full_name}},
65 +
66 + You have registered for {{contest_name}}
67 +
68 + Your login is: {{login}}
69 +
70 + Your password is: {{password}}
71 +
72 + Please follow the link:
73 +
74 + {{activation_url}}
75 +
76 + to activate your user account.
77 +
78 + If you did not register, please ignore this e-mail
79 + and report this event to {{admin_email}}.
80 +
81 + Thanks!"
82 +
83 + email_sent: "We have sent a confimation message to your e-mail. (Please also check the Junk mail box."
84 + email_verify_at: "Please check at {{email}} and confirm."
85 +
86 + activation_sucessful_title: "User activated"
87 + account_activated: "Your account has been activated."
88 +
89 + activation_failed_title: "Activation failed"
90 +
91 + errors:
92 + header: "Errors occured during registration"
93 + email:
94 + title: "Errors in sending registration confirmation"
95 + expl: "<h2>Your user account has been created, but the system cannot send you the confirmation e-mail.</h2>
96 + Maybe there's a problem in the configuration. Please report the admin at {{email}}.<br/>Thank you!"
97 + activation:
98 + email_exists: "A user with this E-mail exists."
99 + invalid: "Your activation code is invalid. Please check again."
100 +
101 + help:
102 + how_to_submit: "How to submit"
103 + must_specify_language: "You <b>must</b> specify the language you are using in your program header. You can optionally specify the task you are submitting to."
104 + list_available_language: "The possible language options are <tt>C</tt>, <tt>C++</tt>, and <tt>Pascal</tt>. The follow are examples."
105 + accept_only_language_specified: "The server <b>will not</b> accept your submission, if you do not specify the language."
106 + specifying_task: "Optionally, you can also specify the task with <tt>TASK:</tt> <i>taskname</i>. On the first page, the taskname for each task is shown in parentheses."
107 + example_cpp: "For example, suppose you are using <tt>C++</tt> to write task <b>mobiles</b>, you put the following on top of your source code."
108 + example_pas: "If you are using <tt>Pascal</tt> to write the same task, you'll use"
109 + ask_questions_at_messages: "If you have any problems, you can ask at [<a href=\"{{url}}\">{{message_link_name}}</a>]."
110 +
111 + activerecord:
112 + attributes:
113 + user:
114 + login: "login"
115 + full_name: "full name"
116 + email: "e-mail"
117 + province: "province"
118 +
@@ -0,0 +1,106
1 + {
2 + :'th' => {
3 + :date => {
4 + :formats => {
5 + :default => lambda { |date| "%d-%m-#{date.year+543}" },
6 + :short => "%e %b",
7 + :long => lambda { |date| "%e %B #{date.year+543}" },
8 + :long_ordinal => lambda { |date| "%e %B #{date.year+543}" },
9 + :only_day => "%e"
10 + },
11 + :day_names => %w(อาทิตย์ จันทร์ อังคาร พุธ พฤหัสบดี ศุกร์ เสาร์),
12 + :abbr_day_names => %w(อา จ อ พ พฤ ศ ส),
13 + :month_names => [nil] + %w(มกราคม กุมภาพันธ์ มีนาคม เมษายน พฤษภาคม มิถุนายน กรกฎาคม สิงหาคม กันยายน ตุลาคม พฤศจิกายน ธันวาคม),
14 + :abbr_month_names => [nil] + %w(ม.ค. ก.พ. มี.ค. เม.ย. พ.ค. มิ.ย. ก.ค. ส.ค. ก.ย. ต.ค. พ.ย. ธ.ค.),
15 + :order => [:day, :month, :year]
16 + },
17 + :time => {
18 + :formats => {
19 + :default => lambda { |time| "%a %d %b #{time.year+543} %H:%M:%S %Z" },
20 + :time => "%H:%M น.",
21 + :short => "%d %b %H:%M น.",
22 + :long => lambda { |time| "%d %B #{time.year+543} %H:%M น." },
23 + :long_ordinal => lambda { |time| "%d %B #{time.year+543} %H:%M น." },
24 + :only_second => "%S"
25 + },
26 + :time_with_zone => {
27 + :formats => {
28 + :default => lambda { |time| "%Y-%m-%d %H:%M:%S #{time.formatted_offset(false, 'UTC')}" }
29 + }
30 + },
31 + :am => '',
32 + :pm => ''
33 + },
34 + :datetime => {
35 + :formats => {
36 + :default => "%Y-%m-%dT%H:%M:%S%Z"
37 + },
38 + :distance_in_words => {
39 + :half_a_minute => 'ครึ่งนาทีที่ผ่านมา',
40 + :less_than_x_seconds => 'น้อยกว่า {{count}} วินาที',
41 + :x_seconds => '{{count}} วินาที',
42 + :less_than_x_minutes => 'น้อยกว่า {{count}} วินาที',
43 + :x_minutes => '{{count}} นาที',
44 + :about_x_hours => 'ประมาณ {{count}} ชั่วโมง',
45 + :x_hours => '{{count}} ชั่วโมง',
46 + :about_x_days => 'ประมาณ {{count}} วัน',
47 + :x_days => '{{count}} วัน',
48 + :about_x_months => 'ประมาณ {{count}} เดือน',
49 + :x_months => '{{count}} เดือน',
50 + :about_x_years => 'ประมาณ {{count}} ปี',
51 + :over_x_years => 'เกิน {{count}} ปี'
52 + }
53 + },
54 +
55 + # numbers
56 + :number => {
57 + :format => {
58 + :precision => 3,
59 + :separator => '.',
60 + :delimiter => ','
61 + },
62 + :currency => {
63 + :format => {
64 + :unit => 'Baht',
65 + :precision => 2,
66 + :format => '%n %u'
67 + }
68 + },
69 + },
70 +
71 + # Active Record
72 + :activerecord => {
73 + :errors => {
74 + :template => {
75 + :header => {
76 + :one => "ไม่สามารถบันทึก {{model}} ได้เนื่องจากเกิดข้อผิดพลาด",
77 + :other => "ไม่สามารถบันทึก {{model}} ได้เนื่องจากเกิด {{count}} ข้อผิดพลาด"
78 + },
79 + :body => "โปรดตรวจสอบข้อมูลที่คุณกรอกในช่องต่อไปนี้:"
80 + },
81 + :messages => {
82 + :inclusion => "ไม่ได้อยู่ในลิสต์",
83 + :exclusion => "ถูกจองเอาไว้แล้ว",
84 + :invalid => "ไม่ถูกต้อง",
85 + :confirmation => "ไม่ตรงกับการยืนยัน",
86 + :accepted => "ต้องอยู่ในรูปแบบที่ยอมรับ",
87 + :empty => "ต้องไม้เว้นว่างเอาไว้",
88 + :blank => "ต้องไม่เว้นว่างเอาไว้",
89 + :too_long => "ยาวเกินไป (ต้องไม่เกิน {{count}} ตัวอักษร)",
90 + :too_short => "สั้นเกินไป (ต้องยาวกว่า {{count}} ตัวอักษร)",
91 + :wrong_length => "มีความยาวไม่ถูกต้อง (ต้องมีความยาว {{count}} ตัวอักษร)",
92 + :taken => "ถูกใช้ไปแล้ว",
93 + :not_a_number => "ไม่ใช่ตัวเลข",
94 + :greater_than => "ต้องมากกว่า {{count}}",
95 + :greater_than_or_equal_to => "ต้องมากกว่าหรือเท่ากับ {{count}}",
96 + :equal_to => "ต้องเท่ากับ {{count}}",
97 + :less_than => "ต้องน้อยกว่า {{count}}",
98 + :less_than_or_equal_to => "ต้องน้อยกว่าหรือเท่ากับ {{count}}",
99 + :odd => "ต้องเป็นเลขคี่",
100 + :even => "ต้องเป็นเลขคู่"
101 + }
102 + }
103 + }
104 + }
105 + }
106 +
@@ -0,0 +1,121
1 + # Sample localization file for English. Add more files in this directory for other locales.
2 + # See http://github.com/svenfuchs/rails-i18n/tree/master/rails%2Flocale for starting points.
3 +
4 + th:
5 + cancel: 'ยกเลิก'
6 +
7 + login_label: 'ชื่อเข้าใช้ระบบ (login)'
8 + full_name_label: 'ชื่อเต็ม'
9 + email_label: 'E-mail'
10 + password_label: 'รหัสผ่าน'
11 +
12 + go_ahead_to: "ไปยัง"
13 + go_back_to: "กลับไปยัง"
14 + login_page: "หน้าเข้าใช้ระบบ"
15 + home_page: "หน้าแรก"
16 +
17 + menu:
18 + main: 'หน้าหลัก'
19 + messages: 'ข้อความ'
20 + tasks: 'โจทย์'
21 + submissions: 'โปรแกรมที่ส่ง'
22 + test: 'ทดสอบโปรแกรม'
23 + help: 'ความช่วยเหลือ'
24 + settings: 'เปลี่ยนรหัสผ่าน'
25 + log_out: 'ออกจากระบบ'
26 +
27 + title_bar:
28 + current_time: "เวลาปัจจุบันคือ"
29 + remaining_time: "เหลือเวลาอีก"
30 + contest_not_started: "ยังไม่เริ่มแข่งขัน"
31 +
32 + login:
33 + message: 'กรุณา login เพื่อเข้าสู่ระบบ'
34 + login_submit: 'เข้าใช้ระบบ'
35 + participation: 'ต้องการเข้าร่วม?'
36 + please: 'กรุณา'
37 + register: 'ลงทะเบียน'
38 +
39 + main:
40 + start_soon: "การแข่งขันกำลังจะเริ่ม กรุณารอก่อน"
41 + specified_in_header: "ระบุที่หัวโปรแกรมแล้ว"
42 +
43 + problem_desc: "อ่าน"
44 + submitted_at: "ส่งเมื่อเวลา"
45 + graded_at: "ตรวจเมื่อเวลา"
46 + score: "คะแนน: "
47 + cmp_msg: "ผลคอมไพล์"
48 + src_link: "ต้นฉบับ"
49 + submissions_link: "การส่งครั้งอื่น ๆ"
50 +
51 + test:
52 + title: "ทดสอบโปรแกรมบนสภาพแวดล้อมของเครื่องตรวจ"
53 + intro: "คุณสามารถทดลองการทำงานของโปรแกรมที่เขียนกับข้อมูลชุดทดสอบของคุณเองในสภาพแวดล้อมจริงของการตรวจโปรแกรมได้ โดยเลือกโปรแกรมส่งแล้วที่ด้านล่างพร้อมทั้งส่งแฟ้มข้อมูลชุดทดสอบที่ต้องการให้ทำงานด้วย"
54 + disabled_at_end_announcement: "<b>หมายเหตุ:</b> ระบบทดสอบโปรแกรมจะหยุดทำงานในช่วงเวลา 30 นาทีสุดท้ายของการแข่งขัน"
55 +
56 +
57 + registration:
58 + title: "ลงทะเบียนผู้ใช้ใหม่"
59 + description: "ในการลงทะเบียน ให้ผู้สนใจเข้าร่วมการแข่งขันกรอกข้อมูลด้านล่าง จากนั้นระบบจะส่ง e-mail ไปยัง e-mail ที่ระบุเพื่อให้ยืนยันตัวตนและเปิดใช้บัญชีผู้ใช้<br/>ในกรณีที่ผู้เข้าแข่งขันเป็นนักเรียน รบกวนช่วยให้ข้อมูลเกี่ยวกับโรงเรียนและจังหวัดด้วย"
60 +
61 + successful_title: "การลงทะเบียนเสร็จเรียบร้อย"
62 +
63 + login_guide: "ใช้ได้เฉพาะ a-z, A-Z, 0-9 และ _ ความยาวไม่เกิน 20 ตัวอักษร"
64 + email_guide: "กรุณาตรวจสอบ e-mail ที่ใส่ให้ถูกต้อง<br/>คุณจะต้องยืนยันการลงทะเบียนผ่านทางข้อมูลที่จะส่งให้ทาง e-mail"
65 + register: "ลงทะเบียน"
66 +
67 + email_body: "สวัสดีครับ {{full_name}},
68 +
69 + คุณได้ลงทะเบียนเข้าร่วมการแข่งขัน {{contest_name}}
70 +
71 + บัญชีเข้าใช้ของคุณคือ: {{login}}
72 +
73 + รหัสผ่านคือ: {{password}}
74 +
75 + กรุณาเข้าลิงก์ต่อไปนี้:
76 +
77 + {{activation_url}}
78 +
79 + เพื่อเปิดใช้งานบัญชีของคุณ
80 +
81 + ถ้าคุณไม่ใช้คนที่ลงทะเบียน กรุณาละทิ้ง e-mail ฉบับนี้
82 + และแจ้งความผิดพลาดนี้กับ {{admin_email}}
83 +
84 + ขอบคุณมาก!"
85 +
86 + email_sent: "เราได้ส่งข้อมูลสำหรับยืนยันไปให้คุณแล้ว (โปรดอย่าลืมตรวจดูในส่วน Junk mail ด้วย)"
87 + email_verify_at: "กรุณาตรวจสอบที่ {{email}} พร้อมทั้งยืนยัน"
88 +
89 + activation_sucessful_title: "บัณชีผู้ใช้ได้รับการยืนยันแล้ว"
90 + account_activated: "บัญชีผู้ใช้ของคุณพร้อมใช้งานแล้ว"
91 +
92 + activation_failed_title: "การยืนยันล้มเหลว"
93 +
94 + errors:
95 + header: 'การลงทะเบียนมีข้อผิดพลาด'
96 + email:
97 + title: "เกิดปัญหาระหว่างการส่ง e-mail เพื่อยืนยันการสมัคร"
98 + expl: "<h2>บัญชีผู้ใช้ของคุณถูกสร้างขึ้นแล้ว แต่ระบบไม่สามารถส่ง e-mail เพื่อยืนยันการสมัครได้</h2>
99 + อาจเกิดปัญหาในการตั้งค่าเริ่มต้นของระบบ กรุณาช่วยติดต่อผู้ดูแลระบบด้วยที่ {{email}}<br/>ขอขอบคุณจากทีมงาน"
100 + activation:
101 + email_exists: "มีผู้ใช้ที่ใช้ e-mail นี้แล้ว"
102 + invalid: "รหัสสำหรับยืนยันผิดพลาด กรุณาตรวจสอบอีกครั้ง"
103 +
104 + help:
105 + how_to_submit: "วิธีการส่งโปรแกรม"
106 + must_specify_language: "คุณ<b>ต้อง</b>ระบุภาษาโปรแกรมที่ใช้ที่ตอนต้นของรหัสโปรแกรม (source code) นอกจากนี้คุณอาจจะระบุโจทย์ที่ต้องการส่งได้ด้วย"
107 + list_available_language: "ภาษาโปรแกรมที่สามารถระบุได้คือ <tt>C</tt>, <tt>C++</tt>, และ <tt>Pascal</tt> ด้านล่างแสดงตัวอย่างของการระบุสำหรับภาษาต่าง ๆ"
108 + accept_only_language_specified: "ระบบจะ<b>ไม่รับ</b>โปรแกรมที่ส่งถ้าคุณไม่ได้ระบุภาษาที่ใช้"
109 + specifying_task: "นอกจากนี้ คุณยังสามารถระบุชื่อของโจทย์ที่ต้องการส่งเพิ่มเติมได้ ในการระบุให้ใส่ <tt>TASK:</tt> <i>taskname</i> คุณสามารถตรวจสอบชื่อของโจทย์ได้ โดยจะแสดงในวงเล็บหลังชื่อภาษาไทยของโจทย์"
110 + example_cpp: "ยกตัวอย่างเช่น ถ้าคุณใช้ภาษา <tt>C++</tt> สำหรับเขียนโจทย์ <tt>mobiles</tt> ตอนต้นโปรแกรมคุณจะใส่ดังนี้"
111 + example_pas: "ถ้าคุณใช้ภาษา <tt>Pascal</tt> เพื่อเขียนโจทย์ข้อเดียวกัน คุณจะระบุ"
112 + ask_questions_at_messages: "ถ้ามีปัญหาในการใช้งานสามารถสอบถามได้ที่หน้า<a href=\"{{url}}\">{{message_link_name}}</a>"
113 +
114 + activerecord:
115 + attributes:
116 + user:
117 + login: "ชื่อเข้าใช้ระบบ"
118 + full_name: "ชื่อเต็ม"
119 + email: "e-mail"
120 + province: "จังหวัด"
121 +
@@ -0,0 +1,31
1 + ---
2 + beads:
3 + testcases: 20
4 + testruns: 20
5 + dna:
6 + testcases: 15
7 + testruns: 15
8 + roads:
9 + testcases: 11
10 + testruns:
11 + 1:
12 + - 1
13 + - 11
14 + 2:
15 + - 2
16 + 3:
17 + - 3
18 + 4:
19 + - 4
20 + 5:
21 + - 5
22 + 6:
23 + - 6
24 + 7:
25 + - 7
26 + 8:
27 + - 8
28 + 9:
29 + - 9
30 + 10:
31 + - 10
@@ -0,0 +1,11
1 + class AddAdminEmailToConfig < ActiveRecord::Migration
2 + def self.up
3 + Configuration.create(:key => 'system.admin_email',
4 + :value_type => 'string',
5 + :value => 'admin@admin.email')
6 + end
7 +
8 + def self.down
9 + Configuration.find_by_key('system.admin_email').destroy
10 + end
11 + end
@@ -0,0 +1,9
1 + class ChangeUserLoginStringLimit < ActiveRecord::Migration
2 + def self.up
3 + execute "ALTER TABLE `users` CHANGE `login` `login` VARCHAR( 50 )"
4 + end
5 +
6 + def self.down
7 + execute "ALTER TABLE `users` CHANGE `login` `login` VARCHAR( 10 )"
8 + end
9 + end
@@ -0,0 +1,15
1 + class AddTestRequestEarlyTimeoutToConfig < ActiveRecord::Migration
2 + def self.up
3 + # If Configuration['contest.test_request.early_timeout'] is true
4 + # the user will not be able to use test request at 30 minutes
5 + # before the contest ends.
6 +
7 + Configuration.create(:key => 'contest.test_request.early_timeout',
8 + :value_type => 'boolean',
9 + :value => 'false')
10 + end
11 +
12 + def self.down
13 + Configuration.find_by_key('contest.test_request.early_timeout').destroy
14 + end
15 + end
@@ -0,0 +1,9
1 + class AddContestFlagToAnnouncements < ActiveRecord::Migration
2 + def self.up
3 + add_column :announcements, :contest_only, :boolean, :default => false
4 + end
5 +
6 + def self.down
7 + remove_column :announcements, :contest_only
8 + end
9 + end
@@ -8,3 +8,12
8 8 require 'rake/rdoctask'
9 9
10 10 require 'tasks/rails'
11 +
12 + require 'spec/rake/spectask'
13 +
14 + desc "Run all examples with RCov"
15 + Spec::Rake::SpecTask.new('examples_with_rcov') do |t|
16 + t.spec_files = FileList['spec/*/*.rb']
17 + t.rcov = true
18 + #t.rcov_opts = ['--exclude', 'examples']
19 + end
@@ -31,12 +31,12
31 31 flash[:notice] = 'Wrong site'
32 32 redirect_to :controller => 'main', :action => 'login' and return
33 33 end
34 - if site.password == params[:login][:password]
34 + if (site.password) and (site.password == params[:login][:password])
35 35 session[:site_id] = site.id
36 36 redirect_to :controller => 'site', :action => 'index'
37 37 else
38 38 flash[:notice] = 'Wrong site password'
39 - redirect_to :controller => 'main', :action => 'login'
39 + redirect_to :controller => 'site', :action => 'login'
40 40 end
41 41 end
42 42
@@ -35,22 +35,6
35 35 # @hidelogin = true
36 36 # end
37 37
38 - # Site administrator login
39 - @countries = Country.find(:all, :include => :sites)
40 - @country_select = @countries.collect { |c| [c.name, c.id] }
41 -
42 - @country_select_with_all = [['Any',0]]
43 - @countries.each do |country|
44 - @country_select_with_all << [country.name, country.id]
45 - end
46 -
47 - @site_select = []
48 - @countries.each do |country|
49 - country.sites.each do |site|
50 - @site_select << ["#{site.name}, #{country.name}", site.id]
51 - end
52 - end
53 -
54 38 @announcements = Announcement.find_for_frontpage
55 39 render :action => 'login', :layout => 'empty'
56 40 end
@@ -197,8 +181,12
197 181 @prob_submissions << { :count => 0, :submission => nil }
198 182 end
199 183 end
184 + if Configuration.show_tasks_to?(@user)
185 + @announcements = Announcement.find_published(true)
186 + else
200 187 @announcements = Announcement.find_published
201 188 end
189 + end
202 190
203 191 def check_viewability
204 192 @user = User.find(session[:user_id])
@@ -1,6 +1,28
1 1 class SiteController < ApplicationController
2 2
3 - before_filter :site_admin_authorization
3 + before_filter :site_admin_authorization, :except => 'login'
4 +
5 + def login
6 + # Site administrator login
7 + @countries = Country.find(:all, :include => :sites)
8 + @country_select = @countries.collect { |c| [c.name, c.id] }
9 +
10 + @country_select_with_all = [['Any',0]]
11 + @countries.each do |country|
12 + @country_select_with_all << [country.name, country.id]
13 + end
14 +
15 + @site_select = []
16 + @countries.each do |country|
17 + country.sites.each do |site|
18 + @site_select << ["#{site.name}, #{country.name}", site.id]
19 + end
20 + end
21 +
22 + @default_site = Site.first if !Configuration['contest.multisites']
23 +
24 + render :action => 'login', :layout => 'empty'
25 + end
4 26
5 27 def index
6 28 if @site.started
@@ -25,7 +47,7
25 47 protected
26 48 def site_admin_authorization
27 49 if session[:site_id]==nil
28 - redirect_to :controller => 'main', :action => 'login' and return
50 + redirect_to :controller => 'site', :action => 'login' and return
29 51 end
30 52 begin
31 53 @site = Site.find(session[:site_id], :include => :country)
@@ -33,7 +55,7
33 55 @site = nil
34 56 end
35 57 if @site==nil
36 - redirect_to :controller => 'main', :action => 'login' and return
58 + redirect_to :controller => 'site', :action => 'login' and return
37 59 end
38 60 end
39 61
@@ -99,7 +99,12
99 99 @problems << problem
100 100 end
101 101 end
102 - @test_requests = @user.test_requests
102 + @test_requests = []
103 + @user.test_requests.each do |ts|
104 + if ts.problem.available
105 + @test_requests << ts
106 + end
107 + end
103 108 end
104 109
105 110 def check_viewability
@@ -13,6 +13,7
13 13
14 14 def list
15 15 @users = User.find(:all)
16 + @hidden_columns = ['hashed_password', 'salt', 'created_at', 'updated_at']
16 17 end
17 18
18 19 def show
@@ -77,8 +78,7
77 78 @scorearray = Array.new
78 79 @users.each do |u|
79 80 ustat = Array.new
80 - ustat[0] = u.login
81 - ustat[1] = u.full_name
81 + ustat[0] = u
82 82 @problems.each do |p|
83 83 sub = Submission.find_last_by_user_and_problem(u.id,p.id)
84 84 if (sub!=nil) and (sub.points!=nil)
@@ -152,7 +152,12
152 152 u.password = user[:password]
153 153 u.country = countries[user[:country_id]]
154 154 u.site = sites[user[:site_id]]
155 - u.save
155 + u.activated = true
156 + u.email = "empty-#{u.login}@none.com"
157 + if not u.save
158 + @import_log << "Errors\n"
159 + u.errors.each { |attr,msg| @import_log << "#{attr} - #{msg}\n" }
160 + end
156 161 end
157 162
158 163 end
@@ -5,11 +5,13
5 5
6 6 before_filter :authenticate, :except => [:new, :register, :confirm]
7 7
8 + before_filter :verify_online_registration, :only => [:new, :register]
9 +
8 10 verify :method => :post, :only => [:chg_passwd],
9 11 :redirect_to => { :action => :index }
10 12
11 - in_place_edit_for :user, :alias_for_editing
12 - in_place_edit_for :user, :email_for_editing
13 + #in_place_edit_for :user, :alias_for_editing
14 + #in_place_edit_for :user, :email_for_editing
13 15
14 16 def index
15 17 if !Configuration['system.user_setting_enabled']
@@ -37,6 +39,10
37 39 end
38 40
39 41 def register
42 + if(params[:cancel])
43 + redirect_to :controller => 'main', :action => 'login'
44 + return
45 + end
40 46 @user = User.new(params[:user])
41 47 @user.password_confirmation = @user.password = User.random_password
42 48 @user.activated = false
@@ -44,6 +50,7
44 50 if send_confirmation_email(@user)
45 51 render :action => 'new_splash', :layout => 'empty'
46 52 else
53 + @admin_email = Configuration['system.admin_email']
47 54 render :action => 'email_error', :layout => 'empty'
48 55 end
49 56 else
@@ -72,8 +79,15
72 79
73 80 protected
74 81
82 + def verify_online_registration
83 + if !Configuration['system.online_registration']
84 + redirect_to :controller => 'main', :action => 'login'
85 + end
86 + end
87 +
75 88 def send_confirmation_email(user)
76 89 contest_name = Configuration['contest.name']
90 + admin_email = Configuration['system.admin_email']
77 91 activation_url = url_for(:action => 'confirm',
78 92 :login => user.login,
79 93 :activation => user.activation_key)
@@ -82,22 +96,16
82 96 mail.to = user.email
83 97 mail.from = Configuration['system.online_registration.from']
84 98 mail.subject = "[#{contest_name}] Confirmation"
85 - mail.body = <<-EOF
86 - Hello #{user.full_name},
87 -
88 - You have registered for #{contest_name} (#{home_url}).
89 -
90 - Your login is: #{user.login}
91 - Your password is: #{user.password}
99 + mail.body = t('registration.email_body', {
100 + :full_name => user.full_name,
101 + :contest_name => contest_name,
102 + :login => user.login,
103 + :password => user.password,
104 + :activation_url => activation_url,
105 + :admin_email => admin_email
106 + })
92 107
93 - Please follow the link:
94 - #{activation_url}
95 - to activate your user account.
96 -
97 - If you did not register, please ignore this e-mail.
98 -
99 - Thanks!
100 - EOF
108 + logger.info mail.body
101 109
102 110 smtp_server = Configuration['system.online_registration.smtp']
103 111
@@ -14,27 +14,28
14 14 append_to menu_items, '[Msg console]', 'messages', 'console'
15 15 append_to menu_items, '[Problem admin]', 'problems', 'index'
16 16 append_to menu_items, '[User admin]', 'user_admin', 'index'
17 - append_to menu_items, '[User stat]', 'user_admin', 'user_stat'
17 + append_to menu_items, '[Results]', 'user_admin', 'user_stat'
18 18 append_to menu_items, '[Graders]', 'graders', 'list'
19 - append_to menu_items, '[Site config]', 'configurations', 'index'
19 + append_to menu_items, '[Sites]', 'sites', 'index'
20 + append_to menu_items, '[System config]', 'configurations', 'index'
20 21 menu_items << "<br/>"
21 22 end
22 23
23 24 # main page
24 - append_to menu_items, '[Main]', 'main', 'list'
25 - append_to menu_items, '[Messages]', 'messages', 'list'
25 + append_to menu_items, "[#{I18n.t 'menu.main'}]", 'main', 'list'
26 + append_to menu_items, "[#{I18n.t 'menu.messages'}]", 'messages', 'list'
26 27
27 28 if (user!=nil) and (Configuration.show_tasks_to?(user))
28 - append_to menu_items, '[Tasks]', 'tasks', 'list'
29 - append_to menu_items, '[Submissions]', 'main', 'submission'
30 - append_to menu_items, '[Test]', 'test', 'index'
29 + append_to menu_items, "[#{I18n.t 'menu.tasks'}]", 'tasks', 'list'
30 + append_to menu_items, "[#{I18n.t 'menu.submissions'}]", 'main', 'submission'
31 + append_to menu_items, "[#{I18n.t 'menu.test'}]", 'test', 'index'
31 32 end
32 - append_to menu_items, '[Help]', 'main', 'help'
33 + append_to menu_items, "[#{I18n.t 'menu.help'}]", 'main', 'help'
33 34
34 35 if Configuration['system.user_setting_enabled']
35 - append_to menu_items, '[Settings]', 'users', 'index'
36 + append_to menu_items, "[#{I18n.t 'menu.settings'}]", 'users', 'index'
36 37 end
37 - append_to menu_items, '[Log out]', 'main', 'login'
38 + append_to menu_items, "[#{I18n.t 'menu.log_out'}]", 'main', 'login'
38 39
39 40 menu_items
40 41 end
@@ -78,8 +79,13
78 79 </td></tr>
79 80 CONTEST_OVER
80 81 end
82 + if !user.site.started
83 + time_left = "&nbsp;&nbsp;" + (t 'title_bar.contest_not_started')
84 + else
81 85 if user.site!=nil
82 - time_left = ". Time left: #{Time.at(user.site.time_left).gmtime.strftime("%X")}"
86 + time_left = "&nbsp;&nbsp;" + (t 'title_bar.remaining_time') +
87 + " #{Time.at(user.site.time_left).gmtime.strftime("%X")}"
88 + end
83 89 end
84 90 end
85 91
@@ -104,7 +110,7
104 110 <tr>
105 111 <td class="left-col">
106 112 #{user.full_name}<br/>
107 - Current time is #{format_short_time(Time.new.gmtime)} UTC
113 + #{t 'title_bar.current_time'} #{format_short_time(Time.new)}
108 114 #{time_left}
109 115 <br/>
110 116 </td>
@@ -1,9 +1,15
1 1 class Announcement < ActiveRecord::Base
2 2
3 - def self.find_published
3 + def self.find_published(contest_started=false)
4 + if contest_started
4 5 Announcement.find(:all,
5 6 :conditions => "(published = 1) AND (frontpage = 0)",
6 7 :order => "created_at DESC")
8 + else
9 + Announcement.find(:all,
10 + :conditions => "(published = 1) AND (frontpage = 0) AND (contest_only = 0)",
11 + :order => "created_at DESC")
12 + end
7 13 end
8 14
9 15 def self.find_for_frontpage
@@ -6,6 +6,7
6 6 class Configuration < ActiveRecord::Base
7 7
8 8 SYSTEM_MODE_CONF_KEY = 'system.mode'
9 + TEST_REQUEST_EARLY_TIMEOUT_KEY = 'contest.test_request.early_timeout'
9 10
10 11 # set @@cache = true to only reload once.
11 12 @@cache = false
@@ -36,6 +37,10
36 37 @@configurations = nil
37 38 end
38 39
40 + def self.cache?
41 + @@cache
42 + end
43 +
39 44 def self.enable_caching
40 45 @@cache = true
41 46 end
@@ -67,8 +72,11
67 72
68 73 def self.allow_test_request(user)
69 74 mode = get(SYSTEM_MODE_CONF_KEY)
75 + early_timeout = get(TEST_REQUEST_EARLY_TIMEOUT_KEY)
70 76 if (mode=='contest')
71 - return false if (user.site!=nil) and ((user.site.started!=true) or (user.site.time_left < 30.minutes))
77 + return false if ((user.site!=nil) and
78 + ((user.site.started!=true) or
79 + (early_timeout and (user.site.time_left < 30.minutes))))
72 80 end
73 81 return false if mode=='analysis'
74 82 return true
@@ -15,11 +15,15
15 15 h = tmatch[1].to_i
16 16 m = tmatch[2].to_i
17 17
18 + contest_time = h.hour + m.minute
19 +
20 + return contest_time if !self.started
21 +
18 22 current_time = Time.now.gmtime
19 23 if self.start_time!=nil
20 - finish_time = self.start_time + h.hour + m.minute
24 + finish_time = self.start_time + contest_time
21 25 else
22 - finish_time = current_time + h.hour + m.minute
26 + finish_time = current_time + contest_time
23 27 end
24 28
25 29 if current_time > finish_time
@@ -23,8 +23,8
23 23
24 24 validates_presence_of :login
25 25 validates_uniqueness_of :login
26 - validates_format_of :login, :with => /^[\_a-z0-9]+$/
27 - validates_length_of :login, :within => 3..10
26 + validates_format_of :login, :with => /^[\_A-Za-z0-9]+$/
27 + validates_length_of :login, :within => 3..30
28 28
29 29 validates_presence_of :full_name
30 30 validates_length_of :full_name, :minimum => 1
@@ -33,14 +33,22
33 33 validates_length_of :password, :within => 4..20, :if => :password_required?
34 34 validates_confirmation_of :password, :if => :password_required?
35 35
36 - validates_format_of :email, :with => /\A([^@\s]+)@((?:[-a-z0-9]+\.)+[a-z]{2,})\Z/i, :allow_blank => true
36 + validates_format_of :email,
37 + :with => /\A([^@\s]+)@((?:[-a-z0-9]+\.)+[a-z]{2,})\Z/i,
38 + :if => :email_validation?
39 + validate :uniqueness_of_email_from_activated_users,
40 + :if => :email_validation?
41 + validate :enough_time_interval_between_same_email_registrations,
42 + :if => :email_validation?
37 43
38 - validate :uniqueness_of_email_from_activated_users
39 - validate :enough_time_interval_between_same_email_registrations
44 + # these are for ytopc
45 + # disable for now
46 + #validates_presence_of :province
40 47
41 48 attr_accessor :password
42 49
43 50 before_save :encrypt_new_password
51 + before_save :assign_default_site
44 52
45 53 def self.authenticate(login, password)
46 54 user = find_by_login(login)
@@ -112,6 +120,16
112 120 self.hashed_password = User.encrypt(self.password,self.salt)
113 121 end
114 122
123 + def assign_default_site
124 + # have to catch error when migrating (because self.site is not available).
125 + begin
126 + if self.site==nil
127 + self.site = Site.find_by_name('default')
128 + end
129 + rescue
130 + end
131 + end
132 +
115 133 def password_required?
116 134 self.hashed_password.blank? || !self.password.blank?
117 135 end
@@ -129,6 +147,7
129 147
130 148 def enough_time_interval_between_same_email_registrations
131 149 return if !self.new_record?
150 + return if self.activated
132 151 open_user = User.find_by_email(self.email,
133 152 :order => 'created_at DESC')
134 153 if open_user and open_user.created_at and
@@ -136,4 +155,12
136 155 self.errors.add_to_base("There are already unactivated registrations with this e-mail address (please wait for 5 minutes)")
137 156 end
138 157 end
158 +
159 + def email_validation?
160 + begin
161 + return VALIDATE_USER_EMAILS
162 + rescue
163 + return false
139 164 end
165 + end
166 + end
@@ -24,6 +24,11
24 24 </p>
25 25
26 26 <p>
27 + <b>Show only in contest?</b><br />
28 + <%= f.check_box :contest_only %>
29 + </p>
30 +
31 + <p>
27 32 <%= f.submit "Update" %>
28 33 </p>
29 34 <% end %>
@@ -1,5 +1,4
1 1 <% content_for :head do %>
2 - <%= stylesheet_link_tag 'scaffold' %>
3 2 <%= javascript_include_tag :defaults %>
4 3 <% end %>
5 4
@@ -24,6 +24,11
24 24 </p>
25 25
26 26 <p>
27 + <b>Show only in contest?</b><br />
28 + <%= f.check_box :contest_only %>
29 + </p>
30 +
31 + <p>
27 32 <%= f.submit "Create" %>
28 33 </p>
29 34 <% end %>
@@ -18,6 +18,10
18 18 <%=h @announcement.frontpage %>
19 19 </p>
20 20
21 + <p>
22 + <b>Show only in contest:</b>
23 + <%=h @announcement.contest_only %>
24 + </p>
21 25
22 26 <%= link_to 'Edit', edit_announcement_path(@announcement) %> |
23 27 <%= link_to 'Back', announcements_path %>
@@ -1,7 +1,7
1 1 - content_for :head do
2 2 = javascript_include_tag :defaults
3 3
4 - %h1 Grader configuration
4 + %h1 System configuration
5 5
6 6 %table.info
7 7 %tr.info-head
@@ -19,6 +19,7
19 19 %td
20 20 = in_place_editor_field :configuration, :value, {}, :rows=>1
21 21
22 + - if Configuration.cache?
22 23 %br/
23 24 Your config is saved, but it does not automatically take effect.
24 25 %br/
@@ -2,16 +2,18
2 2 = stylesheet_link_tag 'graders'
3 3 <meta http-equiv ="refresh" content="10"/>
4 4
5 - %h2 (Under Experiments)
5 + %h1 Grader information
6 6
7 7 - form_for :clear, nil, :url => {:action => 'clear_all'} do |f|
8 8 = submit_tag 'Clear all data'
9 9
10 + - if @last_task
10 11 Last task:
11 12 = link_to "#{@last_task.id}", :action => 'view', :id => @last_task.id, :type => 'Task'
12 13
13 14 %br/
14 15
16 + - if @last_test_request
15 17 Last test_request:
16 18 = link_to "#{@last_test_request.id}", :action => 'view', :id => @last_test_request.id, :type => 'TestRequest'
17 19
@@ -1,4 +1,4
1 1 .announcement
2 2 = markdown(announcement.body)
3 - .pub-info
4 - %p= "#{announcement.author}, #{announcement.created_at}"
3 + -#.pub-info
4 + -# %p= "#{announcement.author}, #{announcement.created_at}"
@@ -4,7 +4,7
4 4 </td>
5 5 <td>
6 6 <%= "#{problem.full_name} (#{problem.name})" %>
7 - <%= link_to '[desc]', problem.url, :popup => true if (problem.url!=nil) and (problem.url!='') %>
7 + <%= link_to "[#{t 'main.problem_desc'}]", problem.url, :popup => true if (problem.url!=nil) and (problem.url!='') %>
8 8 </td>
9 9 <td align="center">
10 10 <%= @prob_submissions[problem_counter][:count] %>
@@ -1,6 +1,6
1 1 <% form_tag({:action => 'submit'}, :multipart => true) do %>
2 2 Problem: <%= select 'submission', 'problem_id',
3 - [['Specified in header','-1']] +
3 + [[(t 'main.specified_in_header'),'-1']] +
4 4 @problems.collect {|p| [p.full_name, p.id]},
5 5 :selected => '-1' %>
6 6 File: <%= file_field_tag 'file' %>
@@ -3,11 +3,14
3 3 = "-"
4 4 - else
5 5 - if submission.graded_at==nil
6 - Submitted at
7 - = format_short_time(submission.submitted_at)
6 + =t 'main.submitted_at'
7 + = format_short_time(submission.submitted_at.localtime)
8 8 - else
9 - = "Graded at #{format_short_time(submission.graded_at)}, "
10 - = "score: #{(submission.points*100/submission.problem.full_score).to_i} " if Configuration['ui.show_score']
9 + = t 'main.graded_at'
10 + = "#{format_short_time(submission.graded_at.localtime)}, "
11 + - if Configuration['ui.show_score']
12 + = t 'main.score'
13 + = "#{(submission.points*100/submission.problem.full_score).to_i} "
11 14 = " ["
12 15 %tt
13 16 = submission.grader_comment
@@ -16,8 +19,8
16 19 = " | "
17 20 = link_to '[detailed result]', :action => 'result', :id => submission.id
18 21 = " | "
19 - = link_to('[msg]', {:action => 'compiler_msg', :id => submission.id}, {:popup => true})
22 + = link_to("[#{t 'main.cmp_msg'}]", {:action => 'compiler_msg', :id => submission.id}, {:popup => true})
20 23 = " | "
21 - = link_to('[src]',{:action => 'source', :id => submission.id})
24 + = link_to("[#{t 'main.src_link'}]",{:action => 'source', :id => submission.id})
22 25 = " | "
23 - = link_to '[submissions]', :action => 'submission', :id => problem_name
26 + = link_to "[#{t 'main.submissions_link'}]", :action => 'submission', :id => problem_name
@@ -2,55 +2,46
2 2
3 3 .announcementbox
4 4 %span{:class => 'title'}
5 - How to submit
5 + =t 'help.how_to_submit'
6 6 .announcement
7 7 %p
8 - You <b>must</b> specify the language you are using
9 - in your program header. You can optionally
10 - specify the task you are submitting to.
8 + =t 'help.must_specify_language'
11 9
12 10 %p
13 - The possible language options are
14 - <tt>C</tt>, <tt>C++</tt>, and <tt>Pascal</tt>.
15 - The follow are examples.
11 + =t 'help.list_available_language'
16 12
17 13 %table{:border => '1'}
18 14 %tr
19 - %th{:width => '100px'} C
20 - %th{:width => '100px'} C++
21 - %th{:width => '100px'} Pascal
15 + %th{:width => '150px'} C
16 + %th{:width => '150px'} C++
17 + %th{:width => '150px'} Pascal
22 18 %tr
23 19 %td= "<tt>/*<br/>LANG: C<br/>*/</tt>"
24 20 %td= "<tt>/*<br/>LANG: C++<br/>*/</tt>"
25 21 %td= "<tt>{<br/>LANG: Pascal<br/>}</tt>"
26 22
27 23 %p
28 - The server <b>will not</b> accept your submission,
29 - if you do not specify the language.
24 + =t 'help.accept_only_language_specified'
30 25
31 26 %p
32 - Optionally, you can also specify
33 - the task with <tt>TASK:</tt> <i>taskname</i>.
34 - On the first page, the taskname for each task is
35 - shown in parentheses.
27 + =t 'help.specifying_task'
36 28
37 29 %p
38 - For example, suppose you are using <tt>C++</tt>
39 - to write task <b>mobiles</b>, you put
30 + =t 'help.example_cpp'
40 31
41 32 %table{:border => '1'}
42 33 %tr
43 - %td{:width => '100px'}
34 + %td{:width => '300px'}
44 35 %tt <tt>/*<br/>LANG: C++<br/>TASK: mobiles<br/>*/</tt>
45 36
46 37 %p
47 - on top of your source code.
48 - If you are using <tt>Pascal</tt> to write the same task,
49 - you'll use
38 + =t 'help.example_pas'
50 39
51 40 %table{:border => '1'}
52 41 %tr
53 - %td{:width => '100px'}
42 + %td{:width => '300px'}
54 43 %tt <tt>{<br/>LANG: Pascal<br/>TASK: mobiles<br/>}</tt>
55 44
45 + %p
46 + = (t('help.ask_questions_at_messages',:message_link_name => (t 'menu.messages'),:url => url_for(:controller => 'messages', :action => 'list')))
56 47
@@ -15,7 +15,7
15 15 %hr/
16 16
17 17 - if (@user.site!=nil) and (@user.site.started!=true)
18 - %p The contest at your site will start soon. Please wait.
18 + %p=t 'main.start_soon'
19 19
20 20 - if Configuration.show_tasks_to?(@user)
21 21 %table.info
@@ -10,7 +10,7
10 10 %br/
11 11
12 12 - if !@hidelogin
13 - Please login to see the problem list.
13 + =t 'login.message'
14 14 %br/
15 15 %br/
16 16
@@ -23,48 +23,20
23 23 - form_tag :controller => 'login', :action => 'login' do
24 24 %table
25 25 %tr
26 - %td{:align => "right"} Login:
26 + %td{:align => "right"}
27 + ="#{t 'login_label'}:"
27 28 %td= text_field_tag 'login'
28 29 %tr
29 - %td{:align => "right"} Password:
30 + %td{:align => "right"}
31 + ="#{t 'password_label'}:"
30 32 %td= password_field_tag
31 - = submit_tag 'Login'
33 + = submit_tag t('login.login_submit')
32 34 %br/
33 35
34 36 - if Configuration['system.online_registration']
35 - Want to participate?
37 + =t 'login.participation'
36 38 %b
37 - Please
38 - = link_to 'register.', :controller => :users, :action => :new
39 + = "#{t 'login.please'} "
40 + = link_to "#{t 'login.register'}", :controller => :users, :action => :new
39 41 %br/
40 42
41 - - if (Configuration['system.mode']=='contest') and (Configuration['contest.multisites'])
42 - %script{:type => 'text/javascript'}
43 - var siteList = new Array();
44 - - @countries.each do |country|
45 - = "siteList[#{country.id}] = new Array();"
46 - - country.sites.each do |site|
47 - = "siteList[#{country.id}][#{site.id}] = \"#{site.name}\";"
48 -
49 - var allSiteList = new Array();
50 - - @site_select.each do |sel|
51 - = "allSiteList[#{sel[1]}]=\"#{sel[0]}\";"
52 -
53 - %script{:type => 'text/javascript', :src => '/javascripts/site_update.js'}
54 -
55 - %div{ :style => "border: solid 1px gray; padding: 2px; background: #f0f0f0;"}
56 - %b For Site Administrator.
57 - %br/
58 - Please select your country and site and login.
59 - - form_for :login, nil, :url => {:controller => 'login', :action => 'site_login'} do |f|
60 - Country:
61 - = select :site_country, :id, @country_select_with_all, {}, {:onchange => "updateSiteList();", :onclick => "updateSiteList();" }
62 - Site:
63 - = select :login, :site_id, @site_select
64 - %br/
65 - Password:
66 - = f.password_field :password
67 - = submit_tag "Site Administrator Login"
68 -
69 - %script{:type => 'text/javascript'}
70 - updateSiteList();
@@ -1,5 +1,4
1 1 <% content_for :head do %>
2 - <%= stylesheet_link_tag 'scaffold' %>
3 2 <%= stylesheet_link_tag 'problems' %>
4 3 <%= javascript_include_tag :defaults %>
5 4 <% end %>
@@ -13,7 +13,7
13 13 <% count = 0 %>
14 14 <% @submissions.each do |sub| %>
15 15 <tr class="<%= (count % 2 ==0) ? "info-even" : "info-odd" %>">
16 - <td><%= sub.user.full_name %></td>
16 + <td><%= sub.user.full_name if sub.user %></td>
17 17 <td><%= sub.submitted_at.to_s %></td>
18 18 <td><%= sub.points %></td>
19 19 <td><div style="font-family: monospace"><%= sub.grader_comment %></div></td>
@@ -1,6 +1,6
1 1 %h2
2 2 Contest Administration for site:
3 - = "#{@site.name}, #{@site.country.name}"
3 + = "#{@site.name}, #{@site.country.name if @site.country}"
4 4
5 5
6 6 Current time at the server is
@@ -1,6 +1,6
1 1 %h2
2 2 Contest Administration for site:
3 - = "#{@site.name}, #{@site.country.name}"
3 + = "#{@site.name}, #{@site.country.name if @site.country}"
4 4
5 5 - curr_time = Time.new.gmtime
6 6
@@ -9,6 +9,11
9 9 </p>
10 10
11 11 <p>
12 + <b>Password</b><br />
13 + <%= f.text_field :password %>
14 + </p>
15 +
16 + <p>
12 17 <b>Started</b><br />
13 18 <%= f.check_box :started %>
14 19 </p>
@@ -3,6 +3,7
3 3 <table>
4 4 <tr>
5 5 <th>Name</th>
6 + <th>Password</th>
6 7 <th>Started</th>
7 8 <th>Start time</th>
8 9 </tr>
@@ -13,6 +14,7
13 14 <% background = "lightgreen" if (site.started==true) and (site.finished? != true) %>
14 15 <tr style="background: <%= background %>;">
15 16 <td><%=h site.name %></td>
17 + <td><%=h site.password %></td>
16 18 <td><%=h site.started %></td>
17 19 <td><%=h site.start_time %></td>
18 20 <td><%= link_to 'Show', site %></td>
@@ -9,6 +9,11
9 9 </p>
10 10
11 11 <p>
12 + <b>Password</b><br />
13 + <%= f.text_field :password %>
14 + </p>
15 +
16 + <p>
12 17 <b>Started</b><br />
13 18 <%= f.check_box :started %>
14 19 </p>
@@ -4,6 +4,11
4 4 </p>
5 5
6 6 <p>
7 + <b>Password:</b>
8 + <%=h @site.password %>
9 + </p>
10 +
11 + <p>
7 12 <b>Started:</b>
8 13 <%=h @site.started %>
9 14 </p>
@@ -1,11 +1,13
1 1 <%= user_title_bar(@user) %>
2 2
3 - <h2>Test Interface</h2>
3 + <h2><%=t 'test.title' %></h2>
4 4
5 - <p>
6 - <b>Note:</b> Test interface will be disabled in the last 30 minutes
7 - of the contest time on your site.
8 - </p>
5 + <div class="test-desc">
6 + <%=t 'test.intro' %><br/>
7 + <% if Configuration['contest.test_request.early_timeout'] %>
8 + <%=t 'test.disabled_at_end_announcement' %>
9 + <% end %>
10 + </div>
9 11
10 12 <% if @problems.length==0 %>
11 13 There is no submission
@@ -69,21 +71,6
69 71 </td>
70 72 </tr>
71 73 <tr>
72 - <td>
73 - Additional file<sup><span style="color:red">*</span></sup>:
74 - </td>
75 - <td>
76 - <%= f.file_field :additional_file %>
77 - </td>
78 - <td>
79 - <small>
80 - * This option works <u>only</u> for task beads.
81 - You can use this to submit <tt>questions.txt</tt>.<br/>
82 - The file shall be copied to the execution directory before your program runs.
83 - </small>
84 - </td>
85 - </tr>
86 - <tr>
87 74 <td colspan="2">
88 75 <%= submit_tag 'submit' %>
89 76 </td>
@@ -27,12 +27,14
27 27 %div{:style => "border: 1px solid black; background: lightgrey"}
28 28 - if @test_request.input_file_name!=nil
29 29 %pre
30 + = ""
30 31 = h(read_textfile(@test_request.input_file_name,2048))
31 32
32 33 %b Output (first 2kb)
33 34 %div{:style => "border: 1px solid black; background: lightgrey"}
34 35 - if @test_request.output_file_name!=nil
35 36 %pre
37 + = ""
36 38 = h(read_textfile(@test_request.output_file_name,2048))
37 39 - else
38 40 (no output)
@@ -13,6 +13,9
13 13 <p><label for="password_confirmation">Password (confirm)</label><br/>
14 14 <%= password_field 'user', 'password_confirmation' %></p>
15 15
16 + <p><label for="user_email">E-mail</label><br/>
17 + <%= text_field 'user', 'email' %></p>
18 +
16 19 <p><label for="user_alias">Alias</label><br/>
17 20 <%= text_field 'user', 'alias' %></p>
18 21 <!--[eoform:user]-->
@@ -1,7 +1,3
1 - <% content_for :head do %>
2 - <%= stylesheet_link_tag 'scaffold' %>
3 - <% end %>
4 -
5 1 <h1>Listing users</h1>
6 2
7 3 <div class="submitbox">
@@ -11,16 +7,16
11 7 <tr>
12 8 <td><label for="user_login">Login</label></td>
13 9 <td><label for="user_full_name">Full name</label></td>
14 - <td><label for="user_alias">Alias</label></td>
15 10 <td><label for="user_password">Password</label></td>
16 - <td><label for="user_password_confirmation">confirm</label></td>
11 + <td><label for="user_password_confirmation">Confirm</label></td>
12 + <td><label for="user_email">Email</label></td>
17 13 </tr>
18 14 <tr>
19 15 <td><%= text_field 'user', 'login', :size => 10 %></td>
20 16 <td><%= text_field 'user', 'full_name', :size => 30 %></td>
21 - <td><%= text_field 'user', 'alias', :size => 10 %></td>
22 17 <td><%= password_field 'user', 'password', :size => 10 %></td>
23 18 <td><%= password_field 'user', 'password_confirmation', :size => 10 %></td>
19 + <td><%= text_field 'user', 'email', :size => 15 %></td>
24 20 <td><%= submit_tag "Create" %></td>
25 21 </tr></table>
26 22 <% end %>
@@ -34,15 +30,19
34 30 <table>
35 31 <tr>
36 32 <% for column in User.content_columns %>
33 + <% if !@hidden_columns.index(column.name) %>
37 34 <th><%= column.human_name %></th>
38 35 <% end %>
36 + <% end %>
39 37 </tr>
40 38
41 39 <% for user in @users %>
42 40 <tr>
43 41 <% for column in User.content_columns %>
42 + <% if !@hidden_columns.index(column.name) %>
44 43 <td><%=h user.send(column.name) %></td>
45 44 <% end %>
45 + <% end %>
46 46 <td><%= link_to 'Show', :action => 'show', :id => user %></td>
47 47 <td><%= link_to 'Edit', :action => 'edit', :id => user %></td>
48 48 <td><%= link_to 'Destroy', { :action => 'destroy', :id => user }, :confirm => 'Are you sure?', :method => :post %></td>
@@ -1,7 +1,10
1 1 <h1>User grading results</h1>
2 2
3 3 <table class="info">
4 - <tr class="info-head"><th>User</th><th>Name</th>
4 + <tr class="info-head">
5 + <th>User</th>
6 + <th>Name</th>
7 + <th>Activated?</th>
5 8 <% @problems.each do |p| %>
6 9 <th><%= p.name %></th>
7 10 <% end %>
@@ -14,8 +17,10
14 17 <% total = 0 %>
15 18 <% num_passed = 0 %>
16 19 <% sc.each_index do |i| %>
17 - <% if i<=1 %>
18 - <td><%= sc[i] %></td>
20 + <% if i==0 %>
21 + <td><%= sc[i].login %></td>
22 + <td><%= sc[i].full_name %></td>
23 + <td><%= sc[i].activated %></td>
19 24 <% else %>
20 25 <td><%= sc[i][0] %></td>
21 26 <% total += sc[i][0] %>
@@ -1,15 +1,17
1 1 - if @result == :successful
2 - %h1 User activated
3 - Your account has been activated.
2 + %h1
3 + =t 'registration.activation_sucessful_title'
4 + =t 'registration.account_activated'
4 5 %br/
5 - Please go ahead to
6 - = link_to 'login.', :controller => 'main', :action => 'login'
6 + =t 'go_ahead_to'
7 + = link_to((t 'login_page'), {:controller => 'main', :action => 'login'})
7 8 - else
8 - %h1 Activation failed
9 + %h1
10 + =t 'registration.activation_failed_title'
9 11 - if @result == :email_used
10 - A user with this E-mail exists.
12 + =t 'registration.errors.activation.email_exists'
11 13 - else
12 - Your activation code is invalid. Please check again.
14 + =t 'registration.errors.activation.invalid'
13 15 %br/
14 - Get back to
15 - = link_to 'home.', :controller => 'main', :action => 'login'
16 + =t 'go_back_to'
17 + = link_to((t 'home_page'), {:controller => 'main', :action => 'login'})
@@ -1,9 +1,8
1 - %h1 Errors in sending registration confirmation
1 + %h1
2 + =t 'registration.errors.email.title'
2 3
3 4 .errorExplanation
4 - %h2
5 - Your user account has been created, but the system cannot send you the
6 - confirmation e-mail.
5 + =t 'registration.errors.email.expl', :email => @admin_email
7 6
8 - Maybe there's a problem in the configuration. Please report the
9 - admin. Thank you!
7 + =t 'go_back_to'
8 + =link_to((t 'login_page'), {:controller => 'main', :action => 'login'})
@@ -5,9 +5,8
5 5
6 6 %h1 Your account settings
7 7
8 - %p
9 - You can edit your alias and e-mails. Just click on the text and edit it.
10 -
8 + -#%p
9 + -#You can edit your alias and e-mails. Just click on the text and edit it.
11 10
12 11 %table.uinfo
13 12 %tr
@@ -16,12 +15,12
16 15 %tr
17 16 %th.uinfo Full name
18 17 %td.uinfo= @user.full_name
19 - %tr
20 - %th.uinfo Alias
21 - %td.uinfo= in_place_editor_field :user, 'alias_for_editing', {}, :rows => 1
22 - %tr
23 - %th.uinfo E-mail
24 - %td.uinfo= in_place_editor_field :user, 'email_for_editing', {}, :rows => 1
18 + -#%tr
19 + -#%th.uinfo Alias
20 + -#%td.uinfo= in_place_editor_field :user, 'alias_for_editing', {}, :rows => 1
21 + -#%tr
22 + -#%th.uinfo E-mail
23 + -#%td.uinfo= in_place_editor_field :user, 'email_for_editing', {}, :rows => 1
25 24 %tr
26 25 %th.uinfo Password
27 26 %td.uinfo
@@ -1,29 +1,39
1 - %h1 New user registration
1 + .contest-title
2 + %h1
3 + = "#{Configuration['contest.name']}: #{t 'registration.title'}"
2 4
3 - = error_messages_for :user, :header_message => 'Errors occured during registration'
5 + .registration-desc
6 + =t 'registration.description'
7 +
8 + = error_messages_for :user, :header_message => (t 'registration.errors.header')
4 9
5 10 %table
6 11 - form_for :user, @user, :url => { :action => 'register' } do |f|
7 12 %tr
8 - %td Login:
13 + %td{:align => "right"}
14 + = "#{t 'login_label'}:"
9 15 %td= f.text_field :login
10 16 %tr
11 17 %td
12 18 %td
13 - %small Only a-z, A-Z, 0-9 and _
19 + %small
20 + =t 'registration.login_guide'
14 21 %tr
15 - %td Full name:
22 + %td{:align => "right"}
23 + = "#{t 'full_name_label'}:"
16 24 %td= f.text_field :full_name
17 25 %tr
18 - %td E-mail:
26 + %td{:align => "right"}
27 + = "#{t 'email_label'}:"
19 28 %td= f.text_field :email
20 29 %tr
21 30 %td
22 31 %td
23 32 %small
24 - Please make sure that your e-mail is correct.
25 - %br/
26 - You'll need to verify your account by email.
33 + =t 'registration.email_guide'
27 34 %tr
28 - %td{:colspan => 2}= submit_tag "Register"
35 + %td/
36 + %td
37 + = submit_tag((t 'registration.register'), :name => 'commit')
38 + = submit_tag((t 'cancel'), :name => 'cancel')
29 39
@@ -1,11 +1,11
1 - %h1 Registration successful
1 + %h1
2 + =t 'registration.successful_title'
2 3
3 - We have sent a confimation message to your e-mail.
4 + =t 'registration.email_sent'
4 5 %br/
5 - Please check at
6 - = "#{@user.email}."
6 + =t 'registration.email_verify_at', :email => @user.email
7 7 %br/
8 8 %br/
9 9
10 - Go back to
11 - = link_to 'login page.', :controller => 'main', :action => 'login'
10 + =t 'go_back_to'
11 + =link_to((t 'login_page'), {:controller => 'main', :action => 'login'})
@@ -5,7 +5,7
5 5 # ENV['RAILS_ENV'] ||= 'production'
6 6
7 7 # Specifies gem version of Rails to use when vendor/rails is not present
8 - RAILS_GEM_VERSION = '2.1.1' unless defined? RAILS_GEM_VERSION
8 + RAILS_GEM_VERSION = '2.3.2' unless defined? RAILS_GEM_VERSION
9 9
10 10 # Bootstrap the Rails environment, frameworks, and default configuration
11 11 require File.join(File.dirname(__FILE__), 'boot')
@@ -39,19 +39,23
39 39 # config.active_record.observers = :cacher, :garbage_collector
40 40
41 41 # Make Active Record use UTC-base instead of local time
42 - config.active_record.default_timezone = :utc
42 + config.time_zone = 'UTC'
43 +
44 + # Setting locales
45 + config.i18n.default_locale = 'th'
43 46
44 47 # See Rails::Configuration for more options
45 48
46 49 # -------------
47 50 # Required gems
48 51 # -------------
49 -
50 - # This is for rspec
51 - config.gem "rspec-rails", :lib => "spec"
52 52 config.gem "haml"
53 53 config.gem "tmail"
54 - #config.gem "BlueCloth", :lig => "bluecloth"
54 + config.gem "BlueCloth", :lib => "bluecloth"
55 +
56 + # NOTES on rspec: if you wan to test with rspec, you have to install
57 + # rspec yourself, just call: [sudo] gem install rspec-rails
58 +
55 59 end
56 60
57 61 # Add new inflection rules using the following format
@@ -73,5 +77,13
73 77 TEST_REQUEST_INPUT_FILE_DIR = RAILS_ROOT + '/data/test_request/input'
74 78 TEST_REQUEST_OUTPUT_FILE_DIR = RAILS_ROOT + '/data/test_request/output'
75 79
80 + # To use ANALYSIS MODE, provide the testcases/testruns breakdown,
81 + # and the directory of the grading result (usually in judge's dir).
82 + TASK_GRADING_INFO_FILENAME = RAILS_ROOT + '/config/tasks.yml'
83 + GRADING_RESULT_DIR = '/home/thailandoi/ytopc/judge/result'
84 +
76 85 # Uncomment so that configuration is read only once when the server is loaded
77 86 # Configuration.enable_caching
87 +
88 + # Uncomment so that the system validates user e-mails
89 + # VALIDATE_USER_EMAILS = true
@@ -14,7 +14,6
14 14 # Show full error reports and disable caching
15 15 config.action_controller.consider_all_requests_local = true
16 16 config.action_controller.perform_caching = false
17 - config.action_view.cache_template_extensions = false
18 17 config.action_view.debug_rjs = true
19 18
20 19 # Don't care if the mailer can't send
@@ -16,4 +16,4
16 16 # Tell ActionMailer not to deliver emails to the real world.
17 17 # The :test delivery method accumulates sent emails in the
18 18 # ActionMailer::Base.deliveries array.
19 - config.action_mailer.delivery_method = :test No newline at end of file
19 + config.action_mailer.delivery_method = :test
@@ -9,7 +9,7
9 9 #
10 10 # It's strongly recommended to check this file into your version control system.
11 11
12 - ActiveRecord::Schema.define(:version => 20081210021333) do
12 + ActiveRecord::Schema.define(:version => 20090206145016) do
13 13
14 14 create_table "announcements", :force => true do |t|
15 15 t.string "author"
@@ -18,6 +18,7
18 18 t.datetime "created_at"
19 19 t.datetime "updated_at"
20 20 t.boolean "frontpage", :default => false
21 + t.boolean "contest_only", :default => false
21 22 end
22 23
23 24 create_table "configurations", :force => true do |t|
@@ -174,7 +175,7
174 175 add_index "test_requests", ["user_id", "problem_id"], :name => "index_test_requests_on_user_id_and_problem_id"
175 176
176 177 create_table "users", :force => true do |t|
177 - t.string "login", :limit => 10
178 + t.string "login", :limit => 50
178 179 t.string "full_name"
179 180 t.string "hashed_password"
180 181 t.string "salt", :limit => 5
@@ -1,6 +1,7
1 1 /* Normal text */
2 - p {
3 - font-size: 12px;
2 + body {
3 + font-size: 13px;
4 + font-family: "Sans Serif";
4 5 }
5 6
6 7 /* This is the main menu bad*/
@@ -227,3 +228,33
227 228 background: green;
228 229 font-weight: bold;
229 230 }
231 +
232 + /********************
233 + Registration
234 + ********************/
235 + div.contest-title {
236 + color: white;
237 + background: #007700;
238 + text-align: center;
239 + padding: 5px;
240 + }
241 +
242 + div.registration-desc {
243 + margin-top: 5px;
244 + margin-bottom: 5px;
245 + border: solid 1px gray;
246 + padding: 10px;
247 + background: #f0f0f0;
248 + }
249 +
250 + /********************
251 + [Test Interface]
252 + ********************/
253 +
254 + div.test-desc {
255 + border: solid 1px gray;
256 + background: #f0f0f0;
257 + padding: 5px;
258 + font-size: 12px;
259 + margin-bottom: 5px;
260 + }
deleted file
deleted file
deleted file
You need to be logged in to leave comments. Login now