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: 921 inserted, 413 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
@@ -1,10 +1,19
1 # Add your own tasks in files placed in lib/tasks ending in .rake,
1 # Add your own tasks in files placed in lib/tasks ending in .rake,
2 # for example lib/tasks/capistrano.rake, and they will automatically be available to Rake.
2 # for example lib/tasks/capistrano.rake, and they will automatically be available to Rake.
3
3
4 require(File.join(File.dirname(__FILE__), 'config', 'boot'))
4 require(File.join(File.dirname(__FILE__), 'config', 'boot'))
5
5
6 require 'rake'
6 require 'rake'
7 require 'rake/testtask'
7 require 'rake/testtask'
8 require 'rake/rdoctask'
8 require 'rake/rdoctask'
9
9
10 require 'tasks/rails'
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
@@ -10,34 +10,34
10 if user = User.authenticate(params[:login], params[:password])
10 if user = User.authenticate(params[:login], params[:password])
11 session[:user_id] = user.id
11 session[:user_id] = user.id
12 redirect_to :controller => 'main', :action => 'list'
12 redirect_to :controller => 'main', :action => 'list'
13 if user.admin?
13 if user.admin?
14 session[:admin] = true
14 session[:admin] = true
15 else
15 else
16 session[:admin] = false
16 session[:admin] = false
17 end
17 end
18 else
18 else
19 flash[:notice] = 'Wrong password'
19 flash[:notice] = 'Wrong password'
20 redirect_to :controller => 'main', :action => 'login'
20 redirect_to :controller => 'main', :action => 'login'
21 end
21 end
22 end
22 end
23
23
24 def site_login
24 def site_login
25 begin
25 begin
26 site = Site.find(params[:login][:site_id])
26 site = Site.find(params[:login][:site_id])
27 rescue ActiveRecord::RecordNotFound
27 rescue ActiveRecord::RecordNotFound
28 site = nil
28 site = nil
29 end
29 end
30 if site==nil
30 if site==nil
31 flash[:notice] = 'Wrong site'
31 flash[:notice] = 'Wrong site'
32 redirect_to :controller => 'main', :action => 'login' and return
32 redirect_to :controller => 'main', :action => 'login' and return
33 end
33 end
34 - if site.password == params[:login][:password]
34 + if (site.password) and (site.password == params[:login][:password])
35 session[:site_id] = site.id
35 session[:site_id] = site.id
36 redirect_to :controller => 'site', :action => 'index'
36 redirect_to :controller => 'site', :action => 'index'
37 else
37 else
38 flash[:notice] = 'Wrong site password'
38 flash[:notice] = 'Wrong site password'
39 - redirect_to :controller => 'main', :action => 'login'
39 + redirect_to :controller => 'site', :action => 'login'
40 end
40 end
41 end
41 end
42
42
43 end
43 end
@@ -14,64 +14,48
14 # COMMENT OUT: only need when having high load
14 # COMMENT OUT: only need when having high load
15 # caches_action :index, :login
15 # caches_action :index, :login
16
16
17 # NOTE: This method is not actually needed, 'config/routes.rb' has
17 # NOTE: This method is not actually needed, 'config/routes.rb' has
18 # assigned action login as a default action.
18 # assigned action login as a default action.
19 def index
19 def index
20 redirect_to :action => 'login'
20 redirect_to :action => 'login'
21 end
21 end
22
22
23 def login
23 def login
24 saved_notice = flash[:notice]
24 saved_notice = flash[:notice]
25 reset_session
25 reset_session
26 flash[:notice] = saved_notice
26 flash[:notice] = saved_notice
27
27
28 # EXPERIMENT:
28 # EXPERIMENT:
29 # Hide login if in single user mode and the url does not
29 # Hide login if in single user mode and the url does not
30 # explicitly specify /login
30 # explicitly specify /login
31 #
31 #
32 # logger.info "PATH: #{request.path}"
32 # logger.info "PATH: #{request.path}"
33 # if Configuration['system.single_user_mode'] and
33 # if Configuration['system.single_user_mode'] and
34 # request.path!='/main/login'
34 # request.path!='/main/login'
35 # @hidelogin = true
35 # @hidelogin = true
36 # end
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 @announcements = Announcement.find_for_frontpage
38 @announcements = Announcement.find_for_frontpage
55 render :action => 'login', :layout => 'empty'
39 render :action => 'login', :layout => 'empty'
56 end
40 end
57
41
58 def list
42 def list
59 prepare_list_information
43 prepare_list_information
60 end
44 end
61
45
62 def help
46 def help
63 @user = User.find(session[:user_id])
47 @user = User.find(session[:user_id])
64 end
48 end
65
49
66 def submit
50 def submit
67 user = User.find(session[:user_id])
51 user = User.find(session[:user_id])
68
52
69 @submission = Submission.new(params[:submission])
53 @submission = Submission.new(params[:submission])
70 @submission.user = user
54 @submission.user = user
71 @submission.language_id = 0
55 @submission.language_id = 0
72 if params['file']!=''
56 if params['file']!=''
73 @submission.source = params['file'].read
57 @submission.source = params['file'].read
74 @submission.source_filename = params['file'].original_filename
58 @submission.source_filename = params['file'].original_filename
75 end
59 end
76 @submission.submitted_at = Time.new.gmtime
60 @submission.submitted_at = Time.new.gmtime
77
61
@@ -176,49 +160,53
176 response.headers['Content-Type'] = "application/force-download"
160 response.headers['Content-Type'] = "application/force-download"
177 response.headers['Content-Disposition'] = "attachment; filename=\"output-#{case_num}.txt\""
161 response.headers['Content-Disposition'] = "attachment; filename=\"output-#{case_num}.txt\""
178 response.headers["X-Sendfile"] = out_filename
162 response.headers["X-Sendfile"] = out_filename
179 response.headers['Content-length'] = File.size(out_filename)
163 response.headers['Content-length'] = File.size(out_filename)
180 render :nothing => true
164 render :nothing => true
181 end
165 end
182
166
183 def error
167 def error
184 @user = User.find(session[:user_id])
168 @user = User.find(session[:user_id])
185 end
169 end
186
170
187 protected
171 protected
188 def prepare_list_information
172 def prepare_list_information
189 @problems = Problem.find_available_problems
173 @problems = Problem.find_available_problems
190 @prob_submissions = Array.new
174 @prob_submissions = Array.new
191 @user = User.find(session[:user_id])
175 @user = User.find(session[:user_id])
192 @problems.each do |p|
176 @problems.each do |p|
193 sub = Submission.find_last_by_user_and_problem(@user.id,p.id)
177 sub = Submission.find_last_by_user_and_problem(@user.id,p.id)
194 if sub!=nil
178 if sub!=nil
195 @prob_submissions << { :count => sub.number, :submission => sub }
179 @prob_submissions << { :count => sub.number, :submission => sub }
196 else
180 else
197 @prob_submissions << { :count => 0, :submission => nil }
181 @prob_submissions << { :count => 0, :submission => nil }
198 end
182 end
199 end
183 end
200 - @announcements = Announcement.find_published
184 + if Configuration.show_tasks_to?(@user)
185 + @announcements = Announcement.find_published(true)
186 + else
187 + @announcements = Announcement.find_published
188 + end
201 end
189 end
202
190
203 def check_viewability
191 def check_viewability
204 @user = User.find(session[:user_id])
192 @user = User.find(session[:user_id])
205 if (!Configuration.show_tasks_to?(@user)) and
193 if (!Configuration.show_tasks_to?(@user)) and
206 ((action_name=='submission') or (action_name=='submit'))
194 ((action_name=='submission') or (action_name=='submit'))
207 redirect_to :action => 'list' and return
195 redirect_to :action => 'list' and return
208 end
196 end
209 end
197 end
210
198
211 def prepare_grading_result(submission)
199 def prepare_grading_result(submission)
212 grading_info = Configuration.task_grading_info[submission.problem.name]
200 grading_info = Configuration.task_grading_info[submission.problem.name]
213 @test_runs = []
201 @test_runs = []
214 if grading_info['testruns'].is_a? Integer
202 if grading_info['testruns'].is_a? Integer
215 trun_count = grading_info['testruns']
203 trun_count = grading_info['testruns']
216 trun_count.times do |i|
204 trun_count.times do |i|
217 @test_runs << [ read_grading_result(@user.login,
205 @test_runs << [ read_grading_result(@user.login,
218 submission.problem.name,
206 submission.problem.name,
219 submission.id,
207 submission.id,
220 i+1) ]
208 i+1) ]
221 end
209 end
222 else
210 else
223 grading_info['testruns'].keys.sort.each do |num|
211 grading_info['testruns'].keys.sort.each do |num|
224 run = []
212 run = []
@@ -1,40 +1,62
1 class SiteController < ApplicationController
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 def index
27 def index
6 if @site.started
28 if @site.started
7 render :action => 'started', :layout => 'empty'
29 render :action => 'started', :layout => 'empty'
8 else
30 else
9 render :action => 'prompt', :layout => 'empty'
31 render :action => 'prompt', :layout => 'empty'
10 end
32 end
11 end
33 end
12
34
13 def start
35 def start
14 @site.started = true
36 @site.started = true
15 @site.start_time = Time.new.gmtime
37 @site.start_time = Time.new.gmtime
16 @site.save
38 @site.save
17 redirect_to :action => 'index'
39 redirect_to :action => 'index'
18 end
40 end
19
41
20 def logout
42 def logout
21 reset_session
43 reset_session
22 redirect_to :controller => 'main', :action => 'login'
44 redirect_to :controller => 'main', :action => 'login'
23 end
45 end
24
46
25 protected
47 protected
26 def site_admin_authorization
48 def site_admin_authorization
27 if session[:site_id]==nil
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 end
51 end
30 begin
52 begin
31 @site = Site.find(session[:site_id], :include => :country)
53 @site = Site.find(session[:site_id], :include => :country)
32 rescue ActiveRecord::RecordNotFound
54 rescue ActiveRecord::RecordNotFound
33 @site = nil
55 @site = nil
34 end
56 end
35 if @site==nil
57 if @site==nil
36 - redirect_to :controller => 'main', :action => 'login' and return
58 + redirect_to :controller => 'site', :action => 'login' and return
37 end
59 end
38 end
60 end
39
61
40 end
62 end
@@ -78,38 +78,43
78 begin
78 begin
79 @test_request = TestRequest.find(params[:id])
79 @test_request = TestRequest.find(params[:id])
80 rescue
80 rescue
81 @test_request = nil
81 @test_request = nil
82 end
82 end
83 if @test_request==nil or @test_request.user_id != @user.id
83 if @test_request==nil or @test_request.user_id != @user.id
84 flash[:notice] = 'Invalid request'
84 flash[:notice] = 'Invalid request'
85 redirect_to :action => 'index'
85 redirect_to :action => 'index'
86 return
86 return
87 end
87 end
88 end
88 end
89
89
90 protected
90 protected
91
91
92 def prepare_index_information
92 def prepare_index_information
93 @user = User.find(session[:user_id])
93 @user = User.find(session[:user_id])
94 @submissions = Submission.find_last_for_all_available_problems(@user.id)
94 @submissions = Submission.find_last_for_all_available_problems(@user.id)
95 all_problems = @submissions.collect { |submission| submission.problem }
95 all_problems = @submissions.collect { |submission| submission.problem }
96 @problems = []
96 @problems = []
97 all_problems.each do |problem|
97 all_problems.each do |problem|
98 if problem.test_allowed
98 if problem.test_allowed
99 @problems << problem
99 @problems << problem
100 end
100 end
101 end
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 end
108 end
104
109
105 def check_viewability
110 def check_viewability
106 user = User.find(session[:user_id])
111 user = User.find(session[:user_id])
107 if !Configuration.show_tasks_to?(user)
112 if !Configuration.show_tasks_to?(user)
108 redirect_to :controller => 'main', :action => 'list'
113 redirect_to :controller => 'main', :action => 'list'
109 end
114 end
110 if (!Configuration.show_submitbox_to?(user)) and (action_name=='submit')
115 if (!Configuration.show_submitbox_to?(user)) and (action_name=='submit')
111 redirect_to :controller => 'test', :action => 'index'
116 redirect_to :controller => 'test', :action => 'index'
112 end
117 end
113 end
118 end
114
119
115 end
120 end
@@ -1,39 +1,40
1 class UserAdminController < ApplicationController
1 class UserAdminController < ApplicationController
2
2
3 before_filter :admin_authorization
3 before_filter :admin_authorization
4
4
5 def index
5 def index
6 list
6 list
7 render :action => 'list'
7 render :action => 'list'
8 end
8 end
9
9
10 # GETs should be safe (see http://www.w3.org/2001/tag/doc/whenToUseGet.html)
10 # GETs should be safe (see http://www.w3.org/2001/tag/doc/whenToUseGet.html)
11 verify :method => :post, :only => [ :destroy, :create, :update ],
11 verify :method => :post, :only => [ :destroy, :create, :update ],
12 :redirect_to => { :action => :list }
12 :redirect_to => { :action => :list }
13
13
14 def list
14 def list
15 @users = User.find(:all)
15 @users = User.find(:all)
16 + @hidden_columns = ['hashed_password', 'salt', 'created_at', 'updated_at']
16 end
17 end
17
18
18 def show
19 def show
19 @user = User.find(params[:id])
20 @user = User.find(params[:id])
20 end
21 end
21
22
22 def new
23 def new
23 @user = User.new
24 @user = User.new
24 end
25 end
25
26
26 def create
27 def create
27 @user = User.new(params[:user])
28 @user = User.new(params[:user])
28 @user.activated = true
29 @user.activated = true
29 if @user.save
30 if @user.save
30 flash[:notice] = 'User was successfully created.'
31 flash[:notice] = 'User was successfully created.'
31 redirect_to :action => 'list'
32 redirect_to :action => 'list'
32 else
33 else
33 render :action => 'new'
34 render :action => 'new'
34 end
35 end
35 end
36 end
36
37
37 def create_from_list
38 def create_from_list
38 lines = params[:user_list]
39 lines = params[:user_list]
39 lines.split("\n").each do |line|
40 lines.split("\n").each do |line|
@@ -56,50 +57,49
56 @user = User.find(params[:id])
57 @user = User.find(params[:id])
57 end
58 end
58
59
59 def update
60 def update
60 @user = User.find(params[:id])
61 @user = User.find(params[:id])
61 if @user.update_attributes(params[:user])
62 if @user.update_attributes(params[:user])
62 flash[:notice] = 'User was successfully updated.'
63 flash[:notice] = 'User was successfully updated.'
63 redirect_to :action => 'show', :id => @user
64 redirect_to :action => 'show', :id => @user
64 else
65 else
65 render :action => 'edit'
66 render :action => 'edit'
66 end
67 end
67 end
68 end
68
69
69 def destroy
70 def destroy
70 User.find(params[:id]).destroy
71 User.find(params[:id]).destroy
71 redirect_to :action => 'list'
72 redirect_to :action => 'list'
72 end
73 end
73
74
74 def user_stat
75 def user_stat
75 @problems = Problem.find_available_problems
76 @problems = Problem.find_available_problems
76 @users = User.find(:all)
77 @users = User.find(:all)
77 @scorearray = Array.new
78 @scorearray = Array.new
78 @users.each do |u|
79 @users.each do |u|
79 ustat = Array.new
80 ustat = Array.new
80 - ustat[0] = u.login
81 + ustat[0] = u
81 - ustat[1] = u.full_name
82 @problems.each do |p|
82 @problems.each do |p|
83 sub = Submission.find_last_by_user_and_problem(u.id,p.id)
83 sub = Submission.find_last_by_user_and_problem(u.id,p.id)
84 if (sub!=nil) and (sub.points!=nil)
84 if (sub!=nil) and (sub.points!=nil)
85 ustat << [(sub.points.to_f*100/p.full_score).round, (sub.points>=p.full_score)]
85 ustat << [(sub.points.to_f*100/p.full_score).round, (sub.points>=p.full_score)]
86 else
86 else
87 ustat << [0,false]
87 ustat << [0,false]
88 end
88 end
89 end
89 end
90 @scorearray << ustat
90 @scorearray << ustat
91 end
91 end
92 end
92 end
93
93
94 def import
94 def import
95 if params[:file]==''
95 if params[:file]==''
96 flash[:notice] = 'Error importing no file'
96 flash[:notice] = 'Error importing no file'
97 redirect_to :action => 'list' and return
97 redirect_to :action => 'list' and return
98 end
98 end
99 import_from_file(params[:file])
99 import_from_file(params[:file])
100 end
100 end
101
101
102 protected
102 protected
103
103
104 def import_from_file(f)
104 def import_from_file(f)
105 data_hash = YAML.load(f)
105 data_hash = YAML.load(f)
@@ -131,30 +131,35
131 @import_log << "Found #{site[:name]}\n"
131 @import_log << "Found #{site[:name]}\n"
132 else
132 else
133 s = Site.new(:name => site[:name])
133 s = Site.new(:name => site[:name])
134 @import_log << "Created #{site[:name]}\n"
134 @import_log << "Created #{site[:name]}\n"
135 end
135 end
136 s.password = site[:password]
136 s.password = site[:password]
137 s.country = countries[site[:country_id]]
137 s.country = countries[site[:country_id]]
138 s.save
138 s.save
139 sites[id] = s
139 sites[id] = s
140 end
140 end
141
141
142 # import users
142 # import users
143 user_data.each_pair do |id,user|
143 user_data.each_pair do |id,user|
144 u = User.find_by_login(user[:login])
144 u = User.find_by_login(user[:login])
145 if u!=nil
145 if u!=nil
146 @import_log << "Found #{user[:login]}\n"
146 @import_log << "Found #{user[:login]}\n"
147 else
147 else
148 u = User.new(:login => user[:login])
148 u = User.new(:login => user[:login])
149 @import_log << "Created #{user[:login]}\n"
149 @import_log << "Created #{user[:login]}\n"
150 end
150 end
151 u.full_name = user[:name]
151 u.full_name = user[:name]
152 u.password = user[:password]
152 u.password = user[:password]
153 u.country = countries[user[:country_id]]
153 u.country = countries[user[:country_id]]
154 u.site = sites[user[:site_id]]
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 end
161 end
157
162
158 end
163 end
159
164
160 end
165 end
@@ -1,116 +1,124
1 require 'tmail'
1 require 'tmail'
2 require 'net/smtp'
2 require 'net/smtp'
3
3
4 class UsersController < ApplicationController
4 class UsersController < ApplicationController
5
5
6 before_filter :authenticate, :except => [:new, :register, :confirm]
6 before_filter :authenticate, :except => [:new, :register, :confirm]
7
7
8 + before_filter :verify_online_registration, :only => [:new, :register]
9 +
8 verify :method => :post, :only => [:chg_passwd],
10 verify :method => :post, :only => [:chg_passwd],
9 :redirect_to => { :action => :index }
11 :redirect_to => { :action => :index }
10
12
11 - in_place_edit_for :user, :alias_for_editing
13 + #in_place_edit_for :user, :alias_for_editing
12 - in_place_edit_for :user, :email_for_editing
14 + #in_place_edit_for :user, :email_for_editing
13
15
14 def index
16 def index
15 if !Configuration['system.user_setting_enabled']
17 if !Configuration['system.user_setting_enabled']
16 redirect_to :controller => 'main', :action => 'list'
18 redirect_to :controller => 'main', :action => 'list'
17 else
19 else
18 @user = User.find(session[:user_id])
20 @user = User.find(session[:user_id])
19 end
21 end
20 end
22 end
21
23
22 def chg_passwd
24 def chg_passwd
23 user = User.find(session[:user_id])
25 user = User.find(session[:user_id])
24 user.password = params[:passwd]
26 user.password = params[:passwd]
25 user.password_confirmation = params[:passwd_verify]
27 user.password_confirmation = params[:passwd_verify]
26 if user.save
28 if user.save
27 flash[:notice] = 'password changed'
29 flash[:notice] = 'password changed'
28 else
30 else
29 flash[:notice] = 'Error: password changing failed'
31 flash[:notice] = 'Error: password changing failed'
30 end
32 end
31 redirect_to :action => 'index'
33 redirect_to :action => 'index'
32 end
34 end
33
35
34 def new
36 def new
35 @user = User.new
37 @user = User.new
36 render :action => 'new', :layout => 'empty'
38 render :action => 'new', :layout => 'empty'
37 end
39 end
38
40
39 def register
41 def register
42 + if(params[:cancel])
43 + redirect_to :controller => 'main', :action => 'login'
44 + return
45 + end
40 @user = User.new(params[:user])
46 @user = User.new(params[:user])
41 @user.password_confirmation = @user.password = User.random_password
47 @user.password_confirmation = @user.password = User.random_password
42 @user.activated = false
48 @user.activated = false
43 if (@user.valid?) and (@user.save)
49 if (@user.valid?) and (@user.save)
44 if send_confirmation_email(@user)
50 if send_confirmation_email(@user)
45 render :action => 'new_splash', :layout => 'empty'
51 render :action => 'new_splash', :layout => 'empty'
46 else
52 else
53 + @admin_email = Configuration['system.admin_email']
47 render :action => 'email_error', :layout => 'empty'
54 render :action => 'email_error', :layout => 'empty'
48 end
55 end
49 else
56 else
50 @user.errors.add_to_base("Email cannot be blank") if @user.email==''
57 @user.errors.add_to_base("Email cannot be blank") if @user.email==''
51 render :action => 'new', :layout => 'empty'
58 render :action => 'new', :layout => 'empty'
52 end
59 end
53 end
60 end
54
61
55 def confirm
62 def confirm
56 login = params[:login]
63 login = params[:login]
57 key = params[:activation]
64 key = params[:activation]
58 @user = User.find_by_login(login)
65 @user = User.find_by_login(login)
59 if (@user) and (@user.verify_activation_key(key))
66 if (@user) and (@user.verify_activation_key(key))
60 if @user.valid? # check uniquenss of email
67 if @user.valid? # check uniquenss of email
61 @user.activated = true
68 @user.activated = true
62 @user.save
69 @user.save
63 @result = :successful
70 @result = :successful
64 else
71 else
65 @result = :email_used
72 @result = :email_used
66 end
73 end
67 else
74 else
68 @result = :failed
75 @result = :failed
69 end
76 end
70 render :action => 'confirm', :layout => 'empty'
77 render :action => 'confirm', :layout => 'empty'
71 end
78 end
72
79
73 protected
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 def send_confirmation_email(user)
88 def send_confirmation_email(user)
76 contest_name = Configuration['contest.name']
89 contest_name = Configuration['contest.name']
90 + admin_email = Configuration['system.admin_email']
77 activation_url = url_for(:action => 'confirm',
91 activation_url = url_for(:action => 'confirm',
78 :login => user.login,
92 :login => user.login,
79 :activation => user.activation_key)
93 :activation => user.activation_key)
80 home_url = url_for(:controller => 'main', :action => 'index')
94 home_url = url_for(:controller => 'main', :action => 'index')
81 mail = TMail::Mail.new
95 mail = TMail::Mail.new
82 mail.to = user.email
96 mail.to = user.email
83 mail.from = Configuration['system.online_registration.from']
97 mail.from = Configuration['system.online_registration.from']
84 mail.subject = "[#{contest_name}] Confirmation"
98 mail.subject = "[#{contest_name}] Confirmation"
85 - mail.body = <<-EOF
99 + mail.body = t('registration.email_body', {
86 - Hello #{user.full_name},
100 + :full_name => user.full_name,
87 -
101 + :contest_name => contest_name,
88 - You have registered for #{contest_name} (#{home_url}).
102 + :login => user.login,
89 -
103 + :password => user.password,
90 - Your login is: #{user.login}
104 + :activation_url => activation_url,
91 - Your password is: #{user.password}
105 + :admin_email => admin_email
106 + })
92
107
93 - Please follow the link:
108 + logger.info mail.body
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
101
109
102 smtp_server = Configuration['system.online_registration.smtp']
110 smtp_server = Configuration['system.online_registration.smtp']
103
111
104 begin
112 begin
105 Net::SMTP.start(smtp_server) do |smtp|
113 Net::SMTP.start(smtp_server) do |smtp|
106 smtp.send_message(mail.to_s, mail.from, mail.to)
114 smtp.send_message(mail.to_s, mail.from, mail.to)
107 end
115 end
108 result = true
116 result = true
109 rescue
117 rescue
110 result = false
118 result = false
111 end
119 end
112
120
113 return result
121 return result
114 end
122 end
115
123
116 end
124 end
@@ -1,118 +1,124
1 # Methods added to this helper will be available to all templates in the application.
1 # Methods added to this helper will be available to all templates in the application.
2 module ApplicationHelper
2 module ApplicationHelper
3
3
4 SYSTEM_MODE_CONF_KEY = 'system.mode'
4 SYSTEM_MODE_CONF_KEY = 'system.mode'
5
5
6 def user_header
6 def user_header
7 menu_items = ''
7 menu_items = ''
8 user = User.find(session[:user_id])
8 user = User.find(session[:user_id])
9
9
10 if (user!=nil) and (session[:admin])
10 if (user!=nil) and (session[:admin])
11 # admin menu
11 # admin menu
12 menu_items << "<b>Administrative task:</b> "
12 menu_items << "<b>Administrative task:</b> "
13 append_to menu_items, '[Announcements]', 'announcements', 'index'
13 append_to menu_items, '[Announcements]', 'announcements', 'index'
14 append_to menu_items, '[Msg console]', 'messages', 'console'
14 append_to menu_items, '[Msg console]', 'messages', 'console'
15 append_to menu_items, '[Problem admin]', 'problems', 'index'
15 append_to menu_items, '[Problem admin]', 'problems', 'index'
16 append_to menu_items, '[User admin]', 'user_admin', 'index'
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 append_to menu_items, '[Graders]', 'graders', 'list'
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 menu_items << "<br/>"
21 menu_items << "<br/>"
21 end
22 end
22
23
23 # main page
24 # main page
24 - append_to menu_items, '[Main]', 'main', 'list'
25 + append_to menu_items, "[#{I18n.t 'menu.main'}]", 'main', 'list'
25 - append_to menu_items, '[Messages]', 'messages', 'list'
26 + append_to menu_items, "[#{I18n.t 'menu.messages'}]", 'messages', 'list'
26
27
27 if (user!=nil) and (Configuration.show_tasks_to?(user))
28 if (user!=nil) and (Configuration.show_tasks_to?(user))
28 - append_to menu_items, '[Tasks]', 'tasks', 'list'
29 + append_to menu_items, "[#{I18n.t 'menu.tasks'}]", 'tasks', 'list'
29 - append_to menu_items, '[Submissions]', 'main', 'submission'
30 + append_to menu_items, "[#{I18n.t 'menu.submissions'}]", 'main', 'submission'
30 - append_to menu_items, '[Test]', 'test', 'index'
31 + append_to menu_items, "[#{I18n.t 'menu.test'}]", 'test', 'index'
31 end
32 end
32 - append_to menu_items, '[Help]', 'main', 'help'
33 + append_to menu_items, "[#{I18n.t 'menu.help'}]", 'main', 'help'
33
34
34 if Configuration['system.user_setting_enabled']
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 end
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 menu_items
40 menu_items
40 end
41 end
41
42
42 def append_to(option,label, controller, action)
43 def append_to(option,label, controller, action)
43 option << ' ' if option!=''
44 option << ' ' if option!=''
44 option << link_to_unless_current(label,
45 option << link_to_unless_current(label,
45 :controller => controller,
46 :controller => controller,
46 :action => action)
47 :action => action)
47 end
48 end
48
49
49 def format_short_time(time)
50 def format_short_time(time)
50 now = Time.now.gmtime
51 now = Time.now.gmtime
51 st = ''
52 st = ''
52 if (time.yday != now.yday) or
53 if (time.yday != now.yday) or
53 (time.year != now.year)
54 (time.year != now.year)
54 st = time.strftime("%x ")
55 st = time.strftime("%x ")
55 end
56 end
56 st + time.strftime("%X")
57 st + time.strftime("%X")
57 end
58 end
58
59
59 def read_textfile(fname,max_size=2048)
60 def read_textfile(fname,max_size=2048)
60 begin
61 begin
61 File.open(fname).read(max_size)
62 File.open(fname).read(max_size)
62 rescue
63 rescue
63 nil
64 nil
64 end
65 end
65 end
66 end
66
67
67 def user_title_bar(user)
68 def user_title_bar(user)
68 header = ''
69 header = ''
69 time_left = ''
70 time_left = ''
70
71
71 #
72 #
72 # if the contest is over
73 # if the contest is over
73 if Configuration[SYSTEM_MODE_CONF_KEY]=='contest'
74 if Configuration[SYSTEM_MODE_CONF_KEY]=='contest'
74 if user.site!=nil and user.site.finished?
75 if user.site!=nil and user.site.finished?
75 header = <<CONTEST_OVER
76 header = <<CONTEST_OVER
76 <tr><td colspan="2" align="center">
77 <tr><td colspan="2" align="center">
77 <span class="contest-over-msg">THE CONTEST IS OVER</span>
78 <span class="contest-over-msg">THE CONTEST IS OVER</span>
78 </td></tr>
79 </td></tr>
79 CONTEST_OVER
80 CONTEST_OVER
80 end
81 end
81 - if user.site!=nil
82 + if !user.site.started
82 - time_left = ". Time left: #{Time.at(user.site.time_left).gmtime.strftime("%X")}"
83 + time_left = "&nbsp;&nbsp;" + (t 'title_bar.contest_not_started')
84 + else
85 + if user.site!=nil
86 + time_left = "&nbsp;&nbsp;" + (t 'title_bar.remaining_time') +
87 + " #{Time.at(user.site.time_left).gmtime.strftime("%X")}"
88 + end
83 end
89 end
84 end
90 end
85
91
86 #
92 #
87 # if the contest is in the anaysis mode
93 # if the contest is in the anaysis mode
88 if Configuration[SYSTEM_MODE_CONF_KEY]=='analysis'
94 if Configuration[SYSTEM_MODE_CONF_KEY]=='analysis'
89 header = <<ANALYSISMODE
95 header = <<ANALYSISMODE
90 <tr><td colspan="2" align="center">
96 <tr><td colspan="2" align="center">
91 <span class="contest-over-msg">ANALYSIS MODE</span>
97 <span class="contest-over-msg">ANALYSIS MODE</span>
92 </td></tr>
98 </td></tr>
93 ANALYSISMODE
99 ANALYSISMODE
94 end
100 end
95
101
96 contest_name = Configuration['contest.name']
102 contest_name = Configuration['contest.name']
97
103
98 #
104 #
99 # build real title bar
105 # build real title bar
100 <<TITLEBAR
106 <<TITLEBAR
101 <div class="title">
107 <div class="title">
102 <table>
108 <table>
103 #{header}
109 #{header}
104 <tr>
110 <tr>
105 <td class="left-col">
111 <td class="left-col">
106 #{user.full_name}<br/>
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 #{time_left}
114 #{time_left}
109 <br/>
115 <br/>
110 </td>
116 </td>
111 <td class="right-col">#{contest_name}</td>
117 <td class="right-col">#{contest_name}</td>
112 </tr>
118 </tr>
113 </table>
119 </table>
114 </div>
120 </div>
115 TITLEBAR
121 TITLEBAR
116 end
122 end
117
123
118 end
124 end
@@ -1,15 +1,21
1 class Announcement < ActiveRecord::Base
1 class Announcement < ActiveRecord::Base
2
2
3 - def self.find_published
3 + def self.find_published(contest_started=false)
4 - Announcement.find(:all,
4 + if contest_started
5 - :conditions => "(published = 1) AND (frontpage = 0)",
5 + Announcement.find(:all,
6 - :order => "created_at DESC")
6 + :conditions => "(published = 1) AND (frontpage = 0)",
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 end
13 end
8
14
9 def self.find_for_frontpage
15 def self.find_for_frontpage
10 Announcement.find(:all,
16 Announcement.find(:all,
11 :conditions => "(published = 1) AND (frontpage = 1)",
17 :conditions => "(published = 1) AND (frontpage = 1)",
12 :order => "created_at DESC")
18 :order => "created_at DESC")
13 end
19 end
14
20
15 end
21 end
@@ -1,95 +1,103
1 require 'yaml'
1 require 'yaml'
2
2
3 #
3 #
4 # This class also contains various login of the system.
4 # This class also contains various login of the system.
5 #
5 #
6 class Configuration < ActiveRecord::Base
6 class Configuration < ActiveRecord::Base
7
7
8 SYSTEM_MODE_CONF_KEY = 'system.mode'
8 SYSTEM_MODE_CONF_KEY = 'system.mode'
9 + TEST_REQUEST_EARLY_TIMEOUT_KEY = 'contest.test_request.early_timeout'
9
10
10 # set @@cache = true to only reload once.
11 # set @@cache = true to only reload once.
11 @@cache = false
12 @@cache = false
12
13
13 @@configurations = nil
14 @@configurations = nil
14 @@task_grading_info = nil
15 @@task_grading_info = nil
15
16
16 def self.get(key)
17 def self.get(key)
17 if @@cache
18 if @@cache
18 if @@configurations == nil
19 if @@configurations == nil
19 self.read_config
20 self.read_config
20 end
21 end
21 return @@configurations[key]
22 return @@configurations[key]
22 else
23 else
23 return Configuration.read_one_key(key)
24 return Configuration.read_one_key(key)
24 end
25 end
25 end
26 end
26
27
27 def self.[](key)
28 def self.[](key)
28 self.get(key)
29 self.get(key)
29 end
30 end
30
31
31 def self.reload
32 def self.reload
32 self.read_config
33 self.read_config
33 end
34 end
34
35
35 def self.clear
36 def self.clear
36 @@configurations = nil
37 @@configurations = nil
37 end
38 end
38
39
40 + def self.cache?
41 + @@cache
42 + end
43 +
39 def self.enable_caching
44 def self.enable_caching
40 @@cache = true
45 @@cache = true
41 end
46 end
42
47
43 #
48 #
44 # View decision
49 # View decision
45 #
50 #
46 def self.show_submitbox_to?(user)
51 def self.show_submitbox_to?(user)
47 mode = get(SYSTEM_MODE_CONF_KEY)
52 mode = get(SYSTEM_MODE_CONF_KEY)
48 return false if mode=='analysis'
53 return false if mode=='analysis'
49 if (mode=='contest')
54 if (mode=='contest')
50 return false if (user.site!=nil) and
55 return false if (user.site!=nil) and
51 ((user.site.started!=true) or (user.site.finished?))
56 ((user.site.started!=true) or (user.site.finished?))
52 end
57 end
53 return true
58 return true
54 end
59 end
55
60
56 def self.show_tasks_to?(user)
61 def self.show_tasks_to?(user)
57 mode = get(SYSTEM_MODE_CONF_KEY)
62 mode = get(SYSTEM_MODE_CONF_KEY)
58 if (mode=='contest')
63 if (mode=='contest')
59 return false if (user.site!=nil) and (user.site.started!=true)
64 return false if (user.site!=nil) and (user.site.started!=true)
60 end
65 end
61 return true
66 return true
62 end
67 end
63
68
64 def self.show_grading_result
69 def self.show_grading_result
65 return (get(SYSTEM_MODE_CONF_KEY)=='analysis')
70 return (get(SYSTEM_MODE_CONF_KEY)=='analysis')
66 end
71 end
67
72
68 def self.allow_test_request(user)
73 def self.allow_test_request(user)
69 mode = get(SYSTEM_MODE_CONF_KEY)
74 mode = get(SYSTEM_MODE_CONF_KEY)
75 + early_timeout = get(TEST_REQUEST_EARLY_TIMEOUT_KEY)
70 if (mode=='contest')
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 end
80 end
73 return false if mode=='analysis'
81 return false if mode=='analysis'
74 return true
82 return true
75 end
83 end
76
84
77 def self.task_grading_info
85 def self.task_grading_info
78 if @@task_grading_info==nil
86 if @@task_grading_info==nil
79 read_grading_info
87 read_grading_info
80 end
88 end
81 return @@task_grading_info
89 return @@task_grading_info
82 end
90 end
83
91
84 protected
92 protected
85
93
86 def self.convert_type(val,type)
94 def self.convert_type(val,type)
87 case type
95 case type
88 when 'string'
96 when 'string'
89 return val
97 return val
90
98
91 when 'integer'
99 when 'integer'
92 return val.to_i
100 return val.to_i
93
101
94 when 'boolean'
102 when 'boolean'
95 return (val=='true')
103 return (val=='true')
@@ -1,46 +1,50
1 class Site < ActiveRecord::Base
1 class Site < ActiveRecord::Base
2
2
3 belongs_to :country
3 belongs_to :country
4 has_many :users
4 has_many :users
5
5
6 def clear_start_time_if_not_started
6 def clear_start_time_if_not_started
7 if !self.started
7 if !self.started
8 self.start_time = nil
8 self.start_time = nil
9 end
9 end
10 end
10 end
11
11
12 def time_left
12 def time_left
13 contest_time = Configuration['contest.time_limit']
13 contest_time = Configuration['contest.time_limit']
14 if tmatch = /(\d+):(\d+)/.match(contest_time)
14 if tmatch = /(\d+):(\d+)/.match(contest_time)
15 h = tmatch[1].to_i
15 h = tmatch[1].to_i
16 m = tmatch[2].to_i
16 m = tmatch[2].to_i
17 +
18 + contest_time = h.hour + m.minute
19 +
20 + return contest_time if !self.started
17
21
18 current_time = Time.now.gmtime
22 current_time = Time.now.gmtime
19 if self.start_time!=nil
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 else
25 else
22 - finish_time = current_time + h.hour + m.minute
26 + finish_time = current_time + contest_time
23 end
27 end
24
28
25 if current_time > finish_time
29 if current_time > finish_time
26 return current_time - current_time
30 return current_time - current_time
27 else
31 else
28 finish_time - current_time
32 finish_time - current_time
29 end
33 end
30 else
34 else
31 nil
35 nil
32 end
36 end
33 end
37 end
34
38
35 def finished?
39 def finished?
36 if !self.started
40 if !self.started
37 return false
41 return false
38 end
42 end
39
43
40 contest_time = Configuration['contest.time_limit']
44 contest_time = Configuration['contest.time_limit']
41 if tmatch = /(\d+):(\d+)/.match(contest_time)
45 if tmatch = /(\d+):(\d+)/.match(contest_time)
42 h = tmatch[1].to_i
46 h = tmatch[1].to_i
43 m = tmatch[2].to_i
47 m = tmatch[2].to_i
44 return Time.now.gmtime > (self.start_time + h.hour + m.minute)
48 return Time.now.gmtime > (self.start_time + h.hour + m.minute)
45 else
49 else
46 false
50 false
@@ -2,66 +2,74
2
2
3 class User < ActiveRecord::Base
3 class User < ActiveRecord::Base
4
4
5 has_and_belongs_to_many :roles
5 has_and_belongs_to_many :roles
6
6
7 has_many :test_requests, :order => "submitted_at DESC"
7 has_many :test_requests, :order => "submitted_at DESC"
8
8
9 has_many :messages,
9 has_many :messages,
10 :class_name => "Message",
10 :class_name => "Message",
11 :foreign_key => "sender_id",
11 :foreign_key => "sender_id",
12 :order => 'created_at DESC'
12 :order => 'created_at DESC'
13
13
14 has_many :replied_messages,
14 has_many :replied_messages,
15 :class_name => "Message",
15 :class_name => "Message",
16 :foreign_key => "receiver_id",
16 :foreign_key => "receiver_id",
17 :order => 'created_at DESC'
17 :order => 'created_at DESC'
18
18
19 belongs_to :site
19 belongs_to :site
20 belongs_to :country
20 belongs_to :country
21
21
22 named_scope :activated_users, :conditions => {:activated => true}
22 named_scope :activated_users, :conditions => {:activated => true}
23
23
24 validates_presence_of :login
24 validates_presence_of :login
25 validates_uniqueness_of :login
25 validates_uniqueness_of :login
26 - validates_format_of :login, :with => /^[\_a-z0-9]+$/
26 + validates_format_of :login, :with => /^[\_A-Za-z0-9]+$/
27 - validates_length_of :login, :within => 3..10
27 + validates_length_of :login, :within => 3..30
28
28
29 validates_presence_of :full_name
29 validates_presence_of :full_name
30 validates_length_of :full_name, :minimum => 1
30 validates_length_of :full_name, :minimum => 1
31
31
32 validates_presence_of :password, :if => :password_required?
32 validates_presence_of :password, :if => :password_required?
33 validates_length_of :password, :within => 4..20, :if => :password_required?
33 validates_length_of :password, :within => 4..20, :if => :password_required?
34 validates_confirmation_of :password, :if => :password_required?
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
44 + # these are for ytopc
39 - validate :enough_time_interval_between_same_email_registrations
45 + # disable for now
46 + #validates_presence_of :province
40
47
41 attr_accessor :password
48 attr_accessor :password
42
49
43 before_save :encrypt_new_password
50 before_save :encrypt_new_password
51 + before_save :assign_default_site
44
52
45 def self.authenticate(login, password)
53 def self.authenticate(login, password)
46 user = find_by_login(login)
54 user = find_by_login(login)
47 return user if user && user.authenticated?(password)
55 return user if user && user.authenticated?(password)
48 end
56 end
49
57
50 def authenticated?(password)
58 def authenticated?(password)
51 if self.activated
59 if self.activated
52 hashed_password == User.encrypt(password,self.salt)
60 hashed_password == User.encrypt(password,self.salt)
53 else
61 else
54 false
62 false
55 end
63 end
56 end
64 end
57
65
58 def admin?
66 def admin?
59 self.roles.detect {|r| r.name == 'admin' }
67 self.roles.detect {|r| r.name == 'admin' }
60 end
68 end
61
69
62 def email_for_editing
70 def email_for_editing
63 if self.email==nil
71 if self.email==nil
64 "(unknown)"
72 "(unknown)"
65 elsif self.email==''
73 elsif self.email==''
66 "(blank)"
74 "(blank)"
67 else
75 else
@@ -91,49 +99,68
91 if self.hashed_password==nil
99 if self.hashed_password==nil
92 encrypt_new_password
100 encrypt_new_password
93 end
101 end
94 Digest::SHA1.hexdigest(self.hashed_password)[0..7]
102 Digest::SHA1.hexdigest(self.hashed_password)[0..7]
95 end
103 end
96
104
97 def verify_activation_key(key)
105 def verify_activation_key(key)
98 key == activation_key
106 key == activation_key
99 end
107 end
100
108
101 def self.random_password(length=5)
109 def self.random_password(length=5)
102 chars = 'abcdefghjkmnopqrstuvwxyz'
110 chars = 'abcdefghjkmnopqrstuvwxyz'
103 password = ''
111 password = ''
104 length.times { password << chars[rand(chars.length - 1)] }
112 length.times { password << chars[rand(chars.length - 1)] }
105 password
113 password
106 end
114 end
107
115
108 protected
116 protected
109 def encrypt_new_password
117 def encrypt_new_password
110 return if password.blank?
118 return if password.blank?
111 self.salt = (10+rand(90)).to_s
119 self.salt = (10+rand(90)).to_s
112 self.hashed_password = User.encrypt(self.password,self.salt)
120 self.hashed_password = User.encrypt(self.password,self.salt)
113 end
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 def password_required?
133 def password_required?
116 self.hashed_password.blank? || !self.password.blank?
134 self.hashed_password.blank? || !self.password.blank?
117 end
135 end
118
136
119 def self.encrypt(string,salt)
137 def self.encrypt(string,salt)
120 Digest::SHA1.hexdigest(salt + string)
138 Digest::SHA1.hexdigest(salt + string)
121 end
139 end
122
140
123 def uniqueness_of_email_from_activated_users
141 def uniqueness_of_email_from_activated_users
124 user = User.activated_users.find_by_email(self.email)
142 user = User.activated_users.find_by_email(self.email)
125 if user and (user.login != self.login)
143 if user and (user.login != self.login)
126 self.errors.add_to_base("Email has already been taken")
144 self.errors.add_to_base("Email has already been taken")
127 end
145 end
128 end
146 end
129
147
130 def enough_time_interval_between_same_email_registrations
148 def enough_time_interval_between_same_email_registrations
131 return if !self.new_record?
149 return if !self.new_record?
150 + return if self.activated
132 open_user = User.find_by_email(self.email,
151 open_user = User.find_by_email(self.email,
133 :order => 'created_at DESC')
152 :order => 'created_at DESC')
134 if open_user and open_user.created_at and
153 if open_user and open_user.created_at and
135 (open_user.created_at > Time.now.gmtime - 5.minutes)
154 (open_user.created_at > Time.now.gmtime - 5.minutes)
136 self.errors.add_to_base("There are already unactivated registrations with this e-mail address (please wait for 5 minutes)")
155 self.errors.add_to_base("There are already unactivated registrations with this e-mail address (please wait for 5 minutes)")
137 end
156 end
138 end
157 end
158 +
159 + def email_validation?
160 + begin
161 + return VALIDATE_USER_EMAILS
162 + rescue
163 + return false
164 + end
165 + end
139 end
166 end
@@ -3,30 +3,35
3 <%= error_messages_for :announcement %>
3 <%= error_messages_for :announcement %>
4
4
5 <% form_for(@announcement) do |f| %>
5 <% form_for(@announcement) do |f| %>
6 <p>
6 <p>
7 <b>Body</b><br />
7 <b>Body</b><br />
8 <%= f.text_area :body %>
8 <%= f.text_area :body %>
9 </p>
9 </p>
10
10
11 <p>
11 <p>
12 <b>Author</b><br />
12 <b>Author</b><br />
13 <%= f.text_field :author %>
13 <%= f.text_field :author %>
14 </p>
14 </p>
15
15
16 <p>
16 <p>
17 <b>Published</b><br />
17 <b>Published</b><br />
18 <%= f.check_box :published %>
18 <%= f.check_box :published %>
19 </p>
19 </p>
20
20
21 <p>
21 <p>
22 <b>Show on front page?</b><br />
22 <b>Show on front page?</b><br />
23 <%= f.check_box :frontpage %>
23 <%= f.check_box :frontpage %>
24 </p>
24 </p>
25
25
26 <p>
26 <p>
27 + <b>Show only in contest?</b><br />
28 + <%= f.check_box :contest_only %>
29 + </p>
30 +
31 + <p>
27 <%= f.submit "Update" %>
32 <%= f.submit "Update" %>
28 </p>
33 </p>
29 <% end %>
34 <% end %>
30
35
31 <%= link_to 'Show', @announcement %> |
36 <%= link_to 'Show', @announcement %> |
32 <%= link_to 'Back', announcements_path %>
37 <%= link_to 'Back', announcements_path %>
@@ -1,26 +1,25
1 <% content_for :head do %>
1 <% content_for :head do %>
2 - <%= stylesheet_link_tag 'scaffold' %>
3 <%= javascript_include_tag :defaults %>
2 <%= javascript_include_tag :defaults %>
4 <% end %>
3 <% end %>
5
4
6 <h1>Listing announcements</h1>
5 <h1>Listing announcements</h1>
7
6
8 <%= link_to 'New announcement', new_announcement_path %>
7 <%= link_to 'New announcement', new_announcement_path %>
9
8
10 <table>
9 <table>
11 <tr>
10 <tr>
12 <th>Body</th>
11 <th>Body</th>
13 <th>Author</th>
12 <th>Author</th>
14 <th>Published</th>
13 <th>Published</th>
15 </tr>
14 </tr>
16
15
17 <% for announcement in @announcements %>
16 <% for announcement in @announcements %>
18 <tr>
17 <tr>
19 <% @announcement = announcement %>
18 <% @announcement = announcement %>
20 <td><%=h announcement.body %></td>
19 <td><%=h announcement.body %></td>
21 <td><%=h announcement.author %></td>
20 <td><%=h announcement.author %></td>
22 <td><%= in_place_editor_field :announcement, :published, {}, :rows => 1 %></td>
21 <td><%= in_place_editor_field :announcement, :published, {}, :rows => 1 %></td>
23 <td><%= link_to 'Show', announcement %></td>
22 <td><%= link_to 'Show', announcement %></td>
24 <td><%= link_to 'Edit', edit_announcement_path(announcement) %></td>
23 <td><%= link_to 'Edit', edit_announcement_path(announcement) %></td>
25 <td><%= link_to 'Destroy', announcement, :confirm => 'Are you sure?', :method => :delete %></td>
24 <td><%= link_to 'Destroy', announcement, :confirm => 'Are you sure?', :method => :delete %></td>
26 </tr>
25 </tr>
@@ -3,29 +3,34
3 <%= error_messages_for :announcement %>
3 <%= error_messages_for :announcement %>
4
4
5 <% form_for(@announcement) do |f| %>
5 <% form_for(@announcement) do |f| %>
6 <p>
6 <p>
7 <b>Body</b><br />
7 <b>Body</b><br />
8 <%= f.text_area :body %>
8 <%= f.text_area :body %>
9 </p>
9 </p>
10
10
11 <p>
11 <p>
12 <b>Author</b><br />
12 <b>Author</b><br />
13 <%= f.text_field :author %>
13 <%= f.text_field :author %>
14 </p>
14 </p>
15
15
16 <p>
16 <p>
17 <b>Published</b><br />
17 <b>Published</b><br />
18 <%= f.check_box :published %>
18 <%= f.check_box :published %>
19 </p>
19 </p>
20
20
21 <p>
21 <p>
22 <b>Show on front page?</b><br />
22 <b>Show on front page?</b><br />
23 <%= f.check_box :frontpage %>
23 <%= f.check_box :frontpage %>
24 </p>
24 </p>
25
25
26 <p>
26 <p>
27 + <b>Show only in contest?</b><br />
28 + <%= f.check_box :contest_only %>
29 + </p>
30 +
31 + <p>
27 <%= f.submit "Create" %>
32 <%= f.submit "Create" %>
28 </p>
33 </p>
29 <% end %>
34 <% end %>
30
35
31 <%= link_to 'Back', announcements_path %>
36 <%= link_to 'Back', announcements_path %>
@@ -1,23 +1,27
1 <p>
1 <p>
2 <b>Author:</b>
2 <b>Author:</b>
3 <%=h @announcement.author %>
3 <%=h @announcement.author %>
4 </p>
4 </p>
5
5
6 <p>
6 <p>
7 <b>Body:</b>
7 <b>Body:</b>
8 <%=h @announcement.body %>
8 <%=h @announcement.body %>
9 </p>
9 </p>
10
10
11 <p>
11 <p>
12 <b>Published:</b>
12 <b>Published:</b>
13 <%=h @announcement.published %>
13 <%=h @announcement.published %>
14 </p>
14 </p>
15
15
16 <p>
16 <p>
17 <b>Show on front page:</b>
17 <b>Show on front page:</b>
18 <%=h @announcement.frontpage %>
18 <%=h @announcement.frontpage %>
19 </p>
19 </p>
20
20
21 + <p>
22 + <b>Show only in contest:</b>
23 + <%=h @announcement.contest_only %>
24 + </p>
21
25
22 <%= link_to 'Edit', edit_announcement_path(@announcement) %> |
26 <%= link_to 'Edit', edit_announcement_path(@announcement) %> |
23 <%= link_to 'Back', announcements_path %>
27 <%= link_to 'Back', announcements_path %>
@@ -1,30 +1,31
1 - content_for :head do
1 - content_for :head do
2 = javascript_include_tag :defaults
2 = javascript_include_tag :defaults
3
3
4 - %h1 Grader configuration
4 + %h1 System configuration
5
5
6 %table.info
6 %table.info
7 %tr.info-head
7 %tr.info-head
8 %th Key
8 %th Key
9 %th Type
9 %th Type
10 %th Value
10 %th Value
11
11
12 - @configurations.each do |conf|
12 - @configurations.each do |conf|
13 - @configuration = conf
13 - @configuration = conf
14 %tr
14 %tr
15 %td
15 %td
16 = in_place_editor_field :configuration, :key, {}, :rows=>1
16 = in_place_editor_field :configuration, :key, {}, :rows=>1
17 %td
17 %td
18 = in_place_editor_field :configuration, :value_type, {}, :rows=>1
18 = in_place_editor_field :configuration, :value_type, {}, :rows=>1
19 %td
19 %td
20 = in_place_editor_field :configuration, :value, {}, :rows=>1
20 = in_place_editor_field :configuration, :value, {}, :rows=>1
21
21
22 - %br/
22 + - if Configuration.cache?
23 - Your config is saved, but it does not automatically take effect.
23 + %br/
24 - %br/
24 + Your config is saved, but it does not automatically take effect.
25 - If you have one mongrel process running, you can
25 + %br/
26 - = link_to '[click]', :action => 'reload'
26 + If you have one mongrel process running, you can
27 - here to reload.
27 + = link_to '[click]', :action => 'reload'
28 - %br/
28 + here to reload.
29 - If you have more than one process running, you should restart
29 + %br/
30 - them manually.
30 + If you have more than one process running, you should restart
31 + them manually.
@@ -1,25 +1,27
1 - content_for :head do
1 - content_for :head do
2 = stylesheet_link_tag 'graders'
2 = stylesheet_link_tag 'graders'
3 <meta http-equiv ="refresh" content="10"/>
3 <meta http-equiv ="refresh" content="10"/>
4
4
5 - %h2 (Under Experiments)
5 + %h1 Grader information
6
6
7 - form_for :clear, nil, :url => {:action => 'clear_all'} do |f|
7 - form_for :clear, nil, :url => {:action => 'clear_all'} do |f|
8 = submit_tag 'Clear all data'
8 = submit_tag 'Clear all data'
9
9
10 - Last task:
10 + - if @last_task
11 - = link_to "#{@last_task.id}", :action => 'view', :id => @last_task.id, :type => 'Task'
11 + Last task:
12 + = link_to "#{@last_task.id}", :action => 'view', :id => @last_task.id, :type => 'Task'
12
13
13 - %br/
14 + %br/
14
15
15 - Last test_request:
16 + - if @last_test_request
16 - = link_to "#{@last_test_request.id}", :action => 'view', :id => @last_test_request.id, :type => 'TestRequest'
17 + Last test_request:
18 + = link_to "#{@last_test_request.id}", :action => 'view', :id => @last_test_request.id, :type => 'TestRequest'
17
19
18
20
19 %h3 Current graders
21 %h3 Current graders
20
22
21 = render :partial => 'grader_list', :locals => {:grader_list => @grader_processes}
23 = render :partial => 'grader_list', :locals => {:grader_list => @grader_processes}
22
24
23 %h3 Stalled graders
25 %h3 Stalled graders
24
26
25 = render :partial => 'grader_list', :locals => {:grader_list => @stalled_processes}
27 = render :partial => 'grader_list', :locals => {:grader_list => @stalled_processes}
@@ -1,4 +1,4
1 .announcement
1 .announcement
2 = markdown(announcement.body)
2 = markdown(announcement.body)
3 - .pub-info
3 + -#.pub-info
4 - %p= "#{announcement.author}, #{announcement.created_at}"
4 + -# %p= "#{announcement.author}, #{announcement.created_at}"
@@ -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.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 </td>
8 </td>
9 <td align="center">
9 <td align="center">
10 <%= @prob_submissions[problem_counter][:count] %>
10 <%= @prob_submissions[problem_counter][: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_counter][:submission],
15 :submission => @prob_submissions[problem_counter][:submission],
16 :problem_name => problem.name }%>
16 :problem_name => problem.name }%>
17 </td>
17 </td>
18 </tr>
18 </tr>
@@ -1,8 +1,8
1 <% form_tag({:action => 'submit'}, :multipart => true) do %>
1 <% form_tag({:action => 'submit'}, :multipart => true) do %>
2 Problem: <%= select 'submission', 'problem_id',
2 Problem: <%= select 'submission', 'problem_id',
3 - [['Specified in header','-1']] +
3 + [[(t 'main.specified_in_header'),'-1']] +
4 @problems.collect {|p| [p.full_name, p.id]},
4 @problems.collect {|p| [p.full_name, p.id]},
5 :selected => '-1' %>
5 :selected => '-1' %>
6 File: <%= file_field_tag 'file' %>
6 File: <%= file_field_tag 'file' %>
7 <%= submit_tag 'Submit' %>
7 <%= submit_tag 'Submit' %>
8 <% end %>
8 <% end %>
@@ -1,23 +1,26
1
1
2 - if submission==nil
2 - if submission==nil
3 = "-"
3 = "-"
4 - else
4 - else
5 - if submission.graded_at==nil
5 - if submission.graded_at==nil
6 - Submitted at
6 + =t 'main.submitted_at'
7 - = format_short_time(submission.submitted_at)
7 + = format_short_time(submission.submitted_at.localtime)
8 - else
8 - else
9 - = "Graded at #{format_short_time(submission.graded_at)}, "
9 + = t 'main.graded_at'
10 - = "score: #{(submission.points*100/submission.problem.full_score).to_i} " if Configuration['ui.show_score']
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 %tt
15 %tt
13 = submission.grader_comment
16 = submission.grader_comment
14 = "]"
17 = "]"
15 - if Configuration.show_grading_result
18 - if Configuration.show_grading_result
16 = " | "
19 = " | "
17 = link_to '[detailed result]', :action => 'result', :id => submission.id
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
@@ -1,56 +1,47
1 = user_title_bar(@user)
1 = user_title_bar(@user)
2
2
3 .announcementbox
3 .announcementbox
4 %span{:class => 'title'}
4 %span{:class => 'title'}
5 - How to submit
5 + =t 'help.how_to_submit'
6 .announcement
6 .announcement
7 %p
7 %p
8 - You <b>must</b> specify the language you are using
8 + =t 'help.must_specify_language'
9 - in your program header. You can optionally
10 - specify the task you are submitting to.
11
9
12 %p
10 %p
13 - The possible language options are
11 + =t 'help.list_available_language'
14 - <tt>C</tt>, <tt>C++</tt>, and <tt>Pascal</tt>.
15 - The follow are examples.
16
12
17 %table{:border => '1'}
13 %table{:border => '1'}
18 %tr
14 %tr
19 - %th{:width => '100px'} C
15 + %th{:width => '150px'} C
20 - %th{:width => '100px'} C++
16 + %th{:width => '150px'} C++
21 - %th{:width => '100px'} Pascal
17 + %th{:width => '150px'} Pascal
22 %tr
18 %tr
23 %td= "<tt>/*<br/>LANG: C<br/>*/</tt>"
19 %td= "<tt>/*<br/>LANG: C<br/>*/</tt>"
24 %td= "<tt>/*<br/>LANG: C++<br/>*/</tt>"
20 %td= "<tt>/*<br/>LANG: C++<br/>*/</tt>"
25 %td= "<tt>{<br/>LANG: Pascal<br/>}</tt>"
21 %td= "<tt>{<br/>LANG: Pascal<br/>}</tt>"
26
22
27 %p
23 %p
28 - The server <b>will not</b> accept your submission,
24 + =t 'help.accept_only_language_specified'
29 - if you do not specify the language.
30
25
31 %p
26 %p
32 - Optionally, you can also specify
27 + =t 'help.specifying_task'
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.
36
28
37 %p
29 %p
38 - For example, suppose you are using <tt>C++</tt>
30 + =t 'help.example_cpp'
39 - to write task <b>mobiles</b>, you put
40
31
41 %table{:border => '1'}
32 %table{:border => '1'}
42 %tr
33 %tr
43 - %td{:width => '100px'}
34 + %td{:width => '300px'}
44 %tt <tt>/*<br/>LANG: C++<br/>TASK: mobiles<br/>*/</tt>
35 %tt <tt>/*<br/>LANG: C++<br/>TASK: mobiles<br/>*/</tt>
45
36
46 %p
37 %p
47 - on top of your source code.
38 + =t 'help.example_pas'
48 - If you are using <tt>Pascal</tt> to write the same task,
49 - you'll use
50
39
51 %table{:border => '1'}
40 %table{:border => '1'}
52 %tr
41 %tr
53 - %td{:width => '100px'}
42 + %td{:width => '300px'}
54 %tt <tt>{<br/>LANG: Pascal<br/>TASK: mobiles<br/>}</tt>
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
@@ -1,30 +1,30
1 = user_title_bar(@user)
1 = user_title_bar(@user)
2
2
3 - if @announcements.length!=0
3 - if @announcements.length!=0
4 .announcementbox
4 .announcementbox
5 %span{:class => 'title'}
5 %span{:class => 'title'}
6 Announcements
6 Announcements
7 = render :partial => 'announcement', :collection => @announcements
7 = render :partial => 'announcement', :collection => @announcements
8
8
9 - if Configuration.show_submitbox_to?(@user)
9 - if Configuration.show_submitbox_to?(@user)
10 .submitbox
10 .submitbox
11 = error_messages_for 'submission'
11 = error_messages_for 'submission'
12 = render :partial => 'submission_box'
12 = render :partial => 'submission_box'
13
13
14
14
15 %hr/
15 %hr/
16
16
17 - if (@user.site!=nil) and (@user.site.started!=true)
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 - if Configuration.show_tasks_to?(@user)
20 - if Configuration.show_tasks_to?(@user)
21 %table.info
21 %table.info
22 %tr.info-head
22 %tr.info-head
23 %th
23 %th
24 %th Tasks
24 %th Tasks
25 %th # of sub(s)
25 %th # of sub(s)
26 %th Results
26 %th Results
27 = render :partial => 'problem', :collection => @problems
27 = render :partial => 'problem', :collection => @problems
28
28
29 %hr/
29 %hr/
30
30
@@ -1,70 +1,42
1 %h1= Configuration['ui.front.title']
1 %h1= Configuration['ui.front.title']
2
2
3 - if @announcements.length!=0
3 - if @announcements.length!=0
4 .announcementbox
4 .announcementbox
5 %span{:class => 'title'}
5 %span{:class => 'title'}
6 Announcements
6 Announcements
7 = render :partial => 'announcement', :collection => @announcements
7 = render :partial => 'announcement', :collection => @announcements
8
8
9 %b= Configuration['ui.front.welcome_message']
9 %b= Configuration['ui.front.welcome_message']
10 %br/
10 %br/
11
11
12 - if !@hidelogin
12 - if !@hidelogin
13 - Please login to see the problem list.
13 + =t 'login.message'
14 %br/
14 %br/
15 %br/
15 %br/
16
16
17 - if flash[:notice]
17 - if flash[:notice]
18 %hr/
18 %hr/
19 %b= flash[:notice]
19 %b= flash[:notice]
20 %hr/
20 %hr/
21
21
22 %div{ :style => "border: solid 1px gray; padding: 2px; background: #f0f0f0;"}
22 %div{ :style => "border: solid 1px gray; padding: 2px; background: #f0f0f0;"}
23 - form_tag :controller => 'login', :action => 'login' do
23 - form_tag :controller => 'login', :action => 'login' do
24 %table
24 %table
25 %tr
25 %tr
26 - %td{:align => "right"} Login:
26 + %td{:align => "right"}
27 + ="#{t 'login_label'}:"
27 %td= text_field_tag 'login'
28 %td= text_field_tag 'login'
28 %tr
29 %tr
29 - %td{:align => "right"} Password:
30 + %td{:align => "right"}
31 + ="#{t 'password_label'}:"
30 %td= password_field_tag
32 %td= password_field_tag
31 - = submit_tag 'Login'
33 + = submit_tag t('login.login_submit')
32 %br/
34 %br/
33
35
34 - if Configuration['system.online_registration']
36 - if Configuration['system.online_registration']
35 - Want to participate?
37 + =t 'login.participation'
36 %b
38 %b
37 - Please
39 + = "#{t 'login.please'} "
38 - = link_to 'register.', :controller => :users, :action => :new
40 + = link_to "#{t 'login.register'}", :controller => :users, :action => :new
39 %br/
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,26 +1,25
1 <% content_for :head do %>
1 <% content_for :head do %>
2 - <%= stylesheet_link_tag 'scaffold' %>
3 <%= stylesheet_link_tag 'problems' %>
2 <%= stylesheet_link_tag 'problems' %>
4 <%= javascript_include_tag :defaults %>
3 <%= javascript_include_tag :defaults %>
5 <% end %>
4 <% end %>
6
5
7 <h1>Listing problems</h1>
6 <h1>Listing problems</h1>
8
7
9 <p>
8 <p>
10 <%= link_to 'New problem', :action => 'new' %>
9 <%= link_to 'New problem', :action => 'new' %>
11 <%= link_to 'Turn off all problems', :action => 'turn_all_off' %>
10 <%= link_to 'Turn off all problems', :action => 'turn_all_off' %>
12 <%= link_to 'Turn on all problems', :action => 'turn_all_on' %>
11 <%= link_to 'Turn on all problems', :action => 'turn_all_on' %>
13 </p>
12 </p>
14
13
15 <table>
14 <table>
16 <tr>
15 <tr>
17 <th>Name</th>
16 <th>Name</th>
18 <th>Full name</th>
17 <th>Full name</th>
19 <th>Full score</th>
18 <th>Full score</th>
20 <th>Date added</th>
19 <th>Date added</th>
21 <th>Avail?</th>
20 <th>Avail?</th>
22 <th>Test?</th>
21 <th>Test?</th>
23 </tr>
22 </tr>
24
23
25 <% for problem in @problems %>
24 <% for problem in @problems %>
26 <tr id="prob-<%= problem.id %>" name="prob-<%= problem.id %>" class="<%= (problem.available) ? "available" : "not-available" %>">
25 <tr id="prob-<%= problem.id %>" name="prob-<%= problem.id %>" class="<%= (problem.available) ? "available" : "not-available" %>">
@@ -1,26 +1,26
1 <h1>Problem stat: <%= @problem.name %></h1>
1 <h1>Problem stat: <%= @problem.name %></h1>
2
2
3 <i>This is just a hack. Really not efficient.</i><br/><br/>
3 <i>This is just a hack. Really not efficient.</i><br/><br/>
4
4
5 <% if @submissions!=nil %>
5 <% if @submissions!=nil %>
6 <table class="info">
6 <table class="info">
7 <tr class="info-head">
7 <tr class="info-head">
8 <th>user_id</th>
8 <th>user_id</th>
9 <th>submitted_at</th>
9 <th>submitted_at</th>
10 <th>points</th>
10 <th>points</th>
11 <th>comment</th>
11 <th>comment</th>
12 </tr>
12 </tr>
13 <% count = 0 %>
13 <% count = 0 %>
14 <% @submissions.each do |sub| %>
14 <% @submissions.each do |sub| %>
15 <tr class="<%= (count % 2 ==0) ? "info-even" : "info-odd" %>">
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 <td><%= sub.submitted_at.to_s %></td>
17 <td><%= sub.submitted_at.to_s %></td>
18 <td><%= sub.points %></td>
18 <td><%= sub.points %></td>
19 <td><div style="font-family: monospace"><%= sub.grader_comment %></div></td>
19 <td><div style="font-family: monospace"><%= sub.grader_comment %></div></td>
20 </tr>
20 </tr>
21 <% count += 1 %>
21 <% count += 1 %>
22 <% end %>
22 <% end %>
23 </table>
23 </table>
24 <% else %>
24 <% else %>
25 No submission
25 No submission
26 <% end %>
26 <% end %>
@@ -1,24 +1,24
1 %h2
1 %h2
2 Contest Administration for site:
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 Current time at the server is
6 Current time at the server is
7 = "#{format_short_time(Time.new.gmtime)} UTC"
7 = "#{format_short_time(Time.new.gmtime)} UTC"
8 (please
8 (please
9 = link_to 'refresh', :action => 'index'
9 = link_to 'refresh', :action => 'index'
10 to update)
10 to update)
11 %br/
11 %br/
12 %br/
12 %br/
13
13
14 - form_tag :action => 'start' do
14 - form_tag :action => 'start' do
15 When you're ready, you can click the button below to start the contest.
15 When you're ready, you can click the button below to start the contest.
16 %br/
16 %br/
17 Please make sure that the contestants are ready.
17 Please make sure that the contestants are ready.
18 After the contest is started, it <b>cannot</b> be paused or stopped.
18 After the contest is started, it <b>cannot</b> be paused or stopped.
19 %br/
19 %br/
20 = submit_tag 'Start the Contest.', :onclick => "return confirm('Are you sure?');"
20 = submit_tag 'Start the Contest.', :onclick => "return confirm('Are you sure?');"
21
21
22 %br/
22 %br/
23 %br/
23 %br/
24 = link_to '[log out]', :action => 'logout'
24 = link_to '[log out]', :action => 'logout'
@@ -1,27 +1,27
1 %h2
1 %h2
2 Contest Administration for site:
2 Contest Administration for site:
3 - = "#{@site.name}, #{@site.country.name}"
3 + = "#{@site.name}, #{@site.country.name if @site.country}"
4
4
5 - curr_time = Time.new.gmtime
5 - curr_time = Time.new.gmtime
6
6
7 - if @site.finished?
7 - if @site.finished?
8 %h3 Contest ended.
8 %h3 Contest ended.
9 - else
9 - else
10 %h3 Contest started.
10 %h3 Contest started.
11
11
12 Current time at the server is
12 Current time at the server is
13 = "#{format_short_time(curr_time)} UTC"
13 = "#{format_short_time(curr_time)} UTC"
14 (please
14 (please
15 = link_to 'refresh', :action => 'index'
15 = link_to 'refresh', :action => 'index'
16 to update)
16 to update)
17 %br/
17 %br/
18 %br/
18 %br/
19
19
20 The contest at your site has been started at
20 The contest at your site has been started at
21 = "#{format_short_time(@site.start_time)} UTC"
21 = "#{format_short_time(@site.start_time)} UTC"
22
22
23 %br/
23 %br/
24
24
25 %h3
25 %h3
26 Time left:
26 Time left:
27 = "#{Time.at(@site.time_left).gmtime.strftime("%X")}"
27 = "#{Time.at(@site.time_left).gmtime.strftime("%X")}"
@@ -1,27 +1,32
1 <h1>Editing site</h1>
1 <h1>Editing site</h1>
2
2
3 <%= error_messages_for :site %>
3 <%= error_messages_for :site %>
4
4
5 <% form_for(@site) do |f| %>
5 <% form_for(@site) do |f| %>
6 <p>
6 <p>
7 <b>Name</b><br />
7 <b>Name</b><br />
8 <%= f.text_field :name %>
8 <%= f.text_field :name %>
9 </p>
9 </p>
10
10
11 <p>
11 <p>
12 + <b>Password</b><br />
13 + <%= f.text_field :password %>
14 + </p>
15 +
16 + <p>
12 <b>Started</b><br />
17 <b>Started</b><br />
13 <%= f.check_box :started %>
18 <%= f.check_box :started %>
14 </p>
19 </p>
15
20
16 <p>
21 <p>
17 <b>Start time</b><br />
22 <b>Start time</b><br />
18 <%= f.datetime_select :start_time %>
23 <%= f.datetime_select :start_time %>
19 </p>
24 </p>
20
25
21 <p>
26 <p>
22 <%= f.submit "Update" %>
27 <%= f.submit "Update" %>
23 </p>
28 </p>
24 <% end %>
29 <% end %>
25
30
26 <%= link_to 'Show', @site %> |
31 <%= link_to 'Show', @site %> |
27 <%= link_to 'Back', sites_path %>
32 <%= link_to 'Back', sites_path %>
@@ -1,27 +1,29
1 <h1>Listing sites</h1>
1 <h1>Listing sites</h1>
2
2
3 <table>
3 <table>
4 <tr>
4 <tr>
5 <th>Name</th>
5 <th>Name</th>
6 + <th>Password</th>
6 <th>Started</th>
7 <th>Started</th>
7 <th>Start time</th>
8 <th>Start time</th>
8 </tr>
9 </tr>
9
10
10 <% for site in @sites %>
11 <% for site in @sites %>
11 <% background = "white" %>
12 <% background = "white" %>
12 <% background = "grey" if (site.started==true) and (site.finished? == true) %>
13 <% background = "grey" if (site.started==true) and (site.finished? == true) %>
13 <% background = "lightgreen" if (site.started==true) and (site.finished? != true) %>
14 <% background = "lightgreen" if (site.started==true) and (site.finished? != true) %>
14 <tr style="background: <%= background %>;">
15 <tr style="background: <%= background %>;">
15 <td><%=h site.name %></td>
16 <td><%=h site.name %></td>
17 + <td><%=h site.password %></td>
16 <td><%=h site.started %></td>
18 <td><%=h site.started %></td>
17 <td><%=h site.start_time %></td>
19 <td><%=h site.start_time %></td>
18 <td><%= link_to 'Show', site %></td>
20 <td><%= link_to 'Show', site %></td>
19 <td><%= link_to 'Edit', edit_site_path(site) %></td>
21 <td><%= link_to 'Edit', edit_site_path(site) %></td>
20 <td><%= link_to 'Destroy', site, :confirm => 'Are you sure?', :method => :delete %></td>
22 <td><%= link_to 'Destroy', site, :confirm => 'Are you sure?', :method => :delete %></td>
21 </tr>
23 </tr>
22 <% end %>
24 <% end %>
23 </table>
25 </table>
24
26
25 <br />
27 <br />
26
28
27 <%= link_to 'New site', new_site_path %>
29 <%= link_to 'New site', new_site_path %>
@@ -1,26 +1,31
1 <h1>New site</h1>
1 <h1>New site</h1>
2
2
3 <%= error_messages_for :site %>
3 <%= error_messages_for :site %>
4
4
5 <% form_for(@site) do |f| %>
5 <% form_for(@site) do |f| %>
6 <p>
6 <p>
7 <b>Name</b><br />
7 <b>Name</b><br />
8 <%= f.text_field :name %>
8 <%= f.text_field :name %>
9 </p>
9 </p>
10
10
11 <p>
11 <p>
12 + <b>Password</b><br />
13 + <%= f.text_field :password %>
14 + </p>
15 +
16 + <p>
12 <b>Started</b><br />
17 <b>Started</b><br />
13 <%= f.check_box :started %>
18 <%= f.check_box :started %>
14 </p>
19 </p>
15
20
16 <p>
21 <p>
17 <b>Start time</b><br />
22 <b>Start time</b><br />
18 <%= f.datetime_select :start_time %>
23 <%= f.datetime_select :start_time %>
19 </p>
24 </p>
20
25
21 <p>
26 <p>
22 <%= f.submit "Create" %>
27 <%= f.submit "Create" %>
23 </p>
28 </p>
24 <% end %>
29 <% end %>
25
30
26 <%= link_to 'Back', sites_path %>
31 <%= link_to 'Back', sites_path %>
@@ -1,18 +1,23
1 <p>
1 <p>
2 <b>Name:</b>
2 <b>Name:</b>
3 <%=h @site.name %>
3 <%=h @site.name %>
4 </p>
4 </p>
5
5
6 <p>
6 <p>
7 + <b>Password:</b>
8 + <%=h @site.password %>
9 + </p>
10 +
11 + <p>
7 <b>Started:</b>
12 <b>Started:</b>
8 <%=h @site.started %>
13 <%=h @site.started %>
9 </p>
14 </p>
10
15
11 <p>
16 <p>
12 <b>Start time:</b>
17 <b>Start time:</b>
13 <%=h @site.start_time %>
18 <%=h @site.start_time %>
14 </p>
19 </p>
15
20
16
21
17 <%= link_to 'Edit', edit_site_path(@site) %> |
22 <%= link_to 'Edit', edit_site_path(@site) %> |
18 <%= link_to 'Back', sites_path %>
23 <%= link_to 'Back', sites_path %>
@@ -1,32 +1,34
1 <%= user_title_bar(@user) %>
1 <%= user_title_bar(@user) %>
2
2
3 - <h2>Test Interface</h2>
3 + <h2><%=t 'test.title' %></h2>
4
4
5 - <p>
5 + <div class="test-desc">
6 - <b>Note:</b> Test interface will be disabled in the last 30 minutes
6 + <%=t 'test.intro' %><br/>
7 - of the contest time on your site.
7 + <% if Configuration['contest.test_request.early_timeout'] %>
8 - </p>
8 + <%=t 'test.disabled_at_end_announcement' %>
9 + <% end %>
10 + </div>
9
11
10 <% if @problems.length==0 %>
12 <% if @problems.length==0 %>
11 There is no submission
13 There is no submission
12 <% else %>
14 <% else %>
13
15
14 <script type="text/javascript">
16 <script type="text/javascript">
15 var submissionCount = new Array();
17 var submissionCount = new Array();
16 <% @submissions.each do |submission| %>
18 <% @submissions.each do |submission| %>
17 submissionCount[<%= submission.problem_id %>]=<%= submission.number %>;
19 submissionCount[<%= submission.problem_id %>]=<%= submission.number %>;
18 <% end %>
20 <% end %>
19
21
20 function updateSubmissionList() {
22 function updateSubmissionList() {
21 currentProb = document.getElementById("test_request_problem_id").value;
23 currentProb = document.getElementById("test_request_problem_id").value;
22 count = submissionCount[currentProb];
24 count = submissionCount[currentProb];
23 submissionSelect = document.getElementById("test_request_submission_number");
25 submissionSelect = document.getElementById("test_request_submission_number");
24 old_len = submissionSelect.length;
26 old_len = submissionSelect.length;
25 // clear the box
27 // clear the box
26 for(i=0; i<old_len; i++)
28 for(i=0; i<old_len; i++)
27 submissionSelect.remove(0);
29 submissionSelect.remove(0);
28 for(i=count; i>=1; i--) {
30 for(i=count; i>=1; i--) {
29 try {
31 try {
30 submissionSelect.add(new Option(""+i,""+i,false,false),null);
32 submissionSelect.add(new Option(""+i,""+i,false,false),null);
31 } catch(ex) {
33 } catch(ex) {
32 submissionSelect.add(new Option(""+i,""+i,false,false));
34 submissionSelect.add(new Option(""+i,""+i,false,false));
@@ -48,63 +50,48
48 <%= select(:test_request,
50 <%= select(:test_request,
49 :problem_id,
51 :problem_id,
50 @problems.collect {|p| [p.name, p.id]}, {},
52 @problems.collect {|p| [p.name, p.id]}, {},
51 { :onclick => "updateSubmissionList();" }) %>
53 { :onclick => "updateSubmissionList();" }) %>
52 </td>
54 </td>
53 </tr>
55 </tr>
54 <tr>
56 <tr>
55 <td>Submission:</td>
57 <td>Submission:</td>
56 <td>
58 <td>
57 <%= select(:test_request,
59 <%= select(:test_request,
58 :submission_number,
60 :submission_number,
59 ((1..@submissions[0].number).collect {|n| [n,n]}).reverse) %>
61 ((1..@submissions[0].number).collect {|n| [n,n]}).reverse) %>
60 </td>
62 </td>
61 </tr>
63 </tr>
62 <tr>
64 <tr>
63 <td>Input data:</td>
65 <td>Input data:</td>
64 <td>
66 <td>
65 <%= f.file_field :input_file %>
67 <%= f.file_field :input_file %>
66 </td>
68 </td>
67 <td>
69 <td>
68 (combined size should not exceed 2MB)
70 (combined size should not exceed 2MB)
69 </td>
71 </td>
70 </tr>
72 </tr>
71 <tr>
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 <td colspan="2">
74 <td colspan="2">
88 <%= submit_tag 'submit' %>
75 <%= submit_tag 'submit' %>
89 </td>
76 </td>
90 </tr>
77 </tr>
91 </table>
78 </table>
92 <% end %>
79 <% end %>
93 </div>
80 </div>
94 <% end %>
81 <% end %>
95
82
96 <h3>Previous requests</h3>
83 <h3>Previous requests</h3>
97
84
98 <table class="info">
85 <table class="info">
99 <tr class="info-head">
86 <tr class="info-head">
100 <th>at</th>
87 <th>at</th>
101 <th>problem</th>
88 <th>problem</th>
102 <th>sub #</th>
89 <th>sub #</th>
103 <th>status</th>
90 <th>status</th>
104 <th>output (first 2kb)</th>
91 <th>output (first 2kb)</th>
105 <th>compiler message</th>
92 <th>compiler message</th>
106 <th>detail</th>
93 <th>detail</th>
107 </tr>
94 </tr>
108 <%= render :partial => 'test_request', :collection => @test_requests %>
95 <%= render :partial => 'test_request', :collection => @test_requests %>
109 </table>
96 </table>
110
97
@@ -6,33 +6,35
6 = "#{@test_request.problem.full_name}"
6 = "#{@test_request.problem.full_name}"
7 - else
7 - else
8 = "(n/a)"
8 = "(n/a)"
9 %br/
9 %br/
10 = "Submission: #{@test_request.submission.number}"
10 = "Submission: #{@test_request.submission.number}"
11 %br/
11 %br/
12 = "Test submitted at: #{format_short_time(@test_request.submitted_at)}"
12 = "Test submitted at: #{format_short_time(@test_request.submitted_at)}"
13 %br/
13 %br/
14 = "Execution time: #{@test_request.running_time} s."
14 = "Execution time: #{@test_request.running_time} s."
15 %br/
15 %br/
16 = "Memory usage: #{@test_request.memory_usage}kb"
16 = "Memory usage: #{@test_request.memory_usage}kb"
17 %br/
17 %br/
18 %b= @test_request.exit_status
18 %b= @test_request.exit_status
19 %br/
19 %br/
20
20
21 - if @test_request.compiler_message!=nil and @test_request.compiler_message!=''
21 - if @test_request.compiler_message!=nil and @test_request.compiler_message!=''
22 %b Compiler Message
22 %b Compiler Message
23 %div{:style => "border: 1px solid black; background: lightgrey"}
23 %div{:style => "border: 1px solid black; background: lightgrey"}
24 = simple_format((@test_request.compiler_message or ''))
24 = simple_format((@test_request.compiler_message or ''))
25
25
26 %b Input (first 2kb)
26 %b Input (first 2kb)
27 %div{:style => "border: 1px solid black; background: lightgrey"}
27 %div{:style => "border: 1px solid black; background: lightgrey"}
28 - if @test_request.input_file_name!=nil
28 - if @test_request.input_file_name!=nil
29 %pre
29 %pre
30 + = ""
30 = h(read_textfile(@test_request.input_file_name,2048))
31 = h(read_textfile(@test_request.input_file_name,2048))
31
32
32 %b Output (first 2kb)
33 %b Output (first 2kb)
33 %div{:style => "border: 1px solid black; background: lightgrey"}
34 %div{:style => "border: 1px solid black; background: lightgrey"}
34 - if @test_request.output_file_name!=nil
35 - if @test_request.output_file_name!=nil
35 %pre
36 %pre
37 + = ""
36 = h(read_textfile(@test_request.output_file_name,2048))
38 = h(read_textfile(@test_request.output_file_name,2048))
37 - else
39 - else
38 (no output)
40 (no output)
@@ -1,19 +1,22
1 <%= error_messages_for 'user' %>
1 <%= error_messages_for 'user' %>
2
2
3 <!--[form:user]-->
3 <!--[form:user]-->
4 <p><label for="user_name">Login</label><br/>
4 <p><label for="user_name">Login</label><br/>
5 <%= text_field 'user', 'login' %></p>
5 <%= text_field 'user', 'login' %></p>
6
6
7 <p><label for="user_name">Full name</label><br/>
7 <p><label for="user_name">Full name</label><br/>
8 <%= text_field 'user', 'full_name' %></p>
8 <%= text_field 'user', 'full_name' %></p>
9
9
10 <p><label for="password">Password</label><br/>
10 <p><label for="password">Password</label><br/>
11 <%= password_field 'user', 'password' %></p>
11 <%= password_field 'user', 'password' %></p>
12
12
13 <p><label for="password_confirmation">Password (confirm)</label><br/>
13 <p><label for="password_confirmation">Password (confirm)</label><br/>
14 <%= password_field 'user', 'password_confirmation' %></p>
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 <p><label for="user_alias">Alias</label><br/>
19 <p><label for="user_alias">Alias</label><br/>
17 <%= text_field 'user', 'alias' %></p>
20 <%= text_field 'user', 'alias' %></p>
18 <!--[eoform:user]-->
21 <!--[eoform:user]-->
19
22
@@ -1,57 +1,57
1 - <% content_for :head do %>
2 - <%= stylesheet_link_tag 'scaffold' %>
3 - <% end %>
4 -
5 <h1>Listing users</h1>
1 <h1>Listing users</h1>
6
2
7 <div class="submitbox">
3 <div class="submitbox">
8 <b>Quick add</b>
4 <b>Quick add</b>
9 <% form_tag :action => 'create' do %>
5 <% form_tag :action => 'create' do %>
10 <table border="0">
6 <table border="0">
11 <tr>
7 <tr>
12 <td><label for="user_login">Login</label></td>
8 <td><label for="user_login">Login</label></td>
13 <td><label for="user_full_name">Full name</label></td>
9 <td><label for="user_full_name">Full name</label></td>
14 - <td><label for="user_alias">Alias</label></td>
15 <td><label for="user_password">Password</label></td>
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 </tr>
13 </tr>
18 <tr>
14 <tr>
19 <td><%= text_field 'user', 'login', :size => 10 %></td>
15 <td><%= text_field 'user', 'login', :size => 10 %></td>
20 <td><%= text_field 'user', 'full_name', :size => 30 %></td>
16 <td><%= text_field 'user', 'full_name', :size => 30 %></td>
21 - <td><%= text_field 'user', 'alias', :size => 10 %></td>
22 <td><%= password_field 'user', 'password', :size => 10 %></td>
17 <td><%= password_field 'user', 'password', :size => 10 %></td>
23 <td><%= password_field 'user', 'password_confirmation', :size => 10 %></td>
18 <td><%= password_field 'user', 'password_confirmation', :size => 10 %></td>
19 + <td><%= text_field 'user', 'email', :size => 15 %></td>
24 <td><%= submit_tag "Create" %></td>
20 <td><%= submit_tag "Create" %></td>
25 </tr></table>
21 </tr></table>
26 <% end %>
22 <% end %>
27 <br/>
23 <br/>
28 <b>Import from site management</b>
24 <b>Import from site management</b>
29 <% form_tag({:action => 'import'}, :multipart => true) do %>
25 <% form_tag({:action => 'import'}, :multipart => true) do %>
30 File: <%= file_field_tag 'file' %> <%= submit_tag 'Import' %>
26 File: <%= file_field_tag 'file' %> <%= submit_tag 'Import' %>
31 <% end %>
27 <% end %>
32
28
33 </div>
29 </div>
34 <table>
30 <table>
35 <tr>
31 <tr>
36 <% for column in User.content_columns %>
32 <% for column in User.content_columns %>
37 - <th><%= column.human_name %></th>
33 + <% if !@hidden_columns.index(column.name) %>
34 + <th><%= column.human_name %></th>
35 + <% end %>
38 <% end %>
36 <% end %>
39 </tr>
37 </tr>
40
38
41 <% for user in @users %>
39 <% for user in @users %>
42 <tr>
40 <tr>
43 <% for column in User.content_columns %>
41 <% for column in User.content_columns %>
44 - <td><%=h user.send(column.name) %></td>
42 + <% if !@hidden_columns.index(column.name) %>
43 + <td><%=h user.send(column.name) %></td>
44 + <% end %>
45 <% end %>
45 <% end %>
46 <td><%= link_to 'Show', :action => 'show', :id => user %></td>
46 <td><%= link_to 'Show', :action => 'show', :id => user %></td>
47 <td><%= link_to 'Edit', :action => 'edit', :id => user %></td>
47 <td><%= link_to 'Edit', :action => 'edit', :id => user %></td>
48 <td><%= link_to 'Destroy', { :action => 'destroy', :id => user }, :confirm => 'Are you sure?', :method => :post %></td>
48 <td><%= link_to 'Destroy', { :action => 'destroy', :id => user }, :confirm => 'Are you sure?', :method => :post %></td>
49 </tr>
49 </tr>
50 <% end %>
50 <% end %>
51 </table>
51 </table>
52
52
53
53
54 <br />
54 <br />
55
55
56 <%= link_to 'New user', :action => 'new' %>
56 <%= link_to 'New user', :action => 'new' %>
57 <%= link_to 'New list of users', :action => 'new_list' %>
57 <%= link_to 'New list of users', :action => 'new_list' %>
@@ -1,30 +1,35
1 <h1>User grading results</h1>
1 <h1>User grading results</h1>
2
2
3 <table class="info">
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 <% @problems.each do |p| %>
8 <% @problems.each do |p| %>
6 <th><%= p.name %></th>
9 <th><%= p.name %></th>
7 <% end %>
10 <% end %>
8 <th>Total</th>
11 <th>Total</th>
9 <th>Passed</th>
12 <th>Passed</th>
10 </tr>
13 </tr>
11 <% counter = 0 %>
14 <% counter = 0 %>
12 <% @scorearray.each do |sc| %>
15 <% @scorearray.each do |sc| %>
13 <tr class="<%= (counter %2 ==0) ? "info-even" : "info-odd" %>">
16 <tr class="<%= (counter %2 ==0) ? "info-even" : "info-odd" %>">
14 <% total = 0 %>
17 <% total = 0 %>
15 <% num_passed = 0 %>
18 <% num_passed = 0 %>
16 <% sc.each_index do |i| %>
19 <% sc.each_index do |i| %>
17 - <% if i<=1 %>
20 + <% if i==0 %>
18 - <td><%= sc[i] %></td>
21 + <td><%= sc[i].login %></td>
22 + <td><%= sc[i].full_name %></td>
23 + <td><%= sc[i].activated %></td>
19 <% else %>
24 <% else %>
20 <td><%= sc[i][0] %></td>
25 <td><%= sc[i][0] %></td>
21 <% total += sc[i][0] %>
26 <% total += sc[i][0] %>
22 <% num_passed += 1 if sc[i][1] %>
27 <% num_passed += 1 if sc[i][1] %>
23 <% end %>
28 <% end %>
24 <% end %>
29 <% end %>
25 <td><%= total %></td>
30 <td><%= total %></td>
26 <td><%= num_passed %></td>
31 <td><%= num_passed %></td>
27 </tr>
32 </tr>
28 <% counter += 1 %>
33 <% counter += 1 %>
29 <% end %>
34 <% end %>
30 </table>
35 </table>
@@ -1,15 +1,17
1 - if @result == :successful
1 - if @result == :successful
2 - %h1 User activated
2 + %h1
3 - Your account has been activated.
3 + =t 'registration.activation_sucessful_title'
4 + =t 'registration.account_activated'
4 %br/
5 %br/
5 - Please go ahead to
6 + =t 'go_ahead_to'
6 - = link_to 'login.', :controller => 'main', :action => 'login'
7 + = link_to((t 'login_page'), {:controller => 'main', :action => 'login'})
7 - else
8 - else
8 - %h1 Activation failed
9 + %h1
10 + =t 'registration.activation_failed_title'
9 - if @result == :email_used
11 - if @result == :email_used
10 - A user with this E-mail exists.
12 + =t 'registration.errors.activation.email_exists'
11 - else
13 - else
12 - Your activation code is invalid. Please check again.
14 + =t 'registration.errors.activation.invalid'
13 %br/
15 %br/
14 - Get back to
16 + =t 'go_back_to'
15 - = link_to 'home.', :controller => 'main', :action => 'login'
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 .errorExplanation
4 .errorExplanation
4 - %h2
5 + =t 'registration.errors.email.expl', :email => @admin_email
5 - Your user account has been created, but the system cannot send you the
6 - confirmation e-mail.
7
6
8 - Maybe there's a problem in the configuration. Please report the
7 + =t 'go_back_to'
9 - admin. Thank you!
8 + =link_to((t 'login_page'), {:controller => 'main', :action => 'login'})
@@ -1,39 +1,38
1 - content_for :head do
1 - content_for :head do
2 = javascript_include_tag :defaults
2 = javascript_include_tag :defaults
3
3
4 = user_title_bar(@user)
4 = user_title_bar(@user)
5
5
6 %h1 Your account settings
6 %h1 Your account settings
7
7
8 - %p
8 + -#%p
9 - You can edit your alias and e-mails. Just click on the text and edit it.
9 + -#You can edit your alias and e-mails. Just click on the text and edit it.
10 -
11
10
12 %table.uinfo
11 %table.uinfo
13 %tr
12 %tr
14 %th.uinfo Login
13 %th.uinfo Login
15 %td.uinfo= @user.login
14 %td.uinfo= @user.login
16 %tr
15 %tr
17 %th.uinfo Full name
16 %th.uinfo Full name
18 %td.uinfo= @user.full_name
17 %td.uinfo= @user.full_name
19 - %tr
18 + -#%tr
20 - %th.uinfo Alias
19 + -#%th.uinfo Alias
21 - %td.uinfo= in_place_editor_field :user, 'alias_for_editing', {}, :rows => 1
20 + -#%td.uinfo= in_place_editor_field :user, 'alias_for_editing', {}, :rows => 1
22 - %tr
21 + -#%tr
23 - %th.uinfo E-mail
22 + -#%th.uinfo E-mail
24 - %td.uinfo= in_place_editor_field :user, 'email_for_editing', {}, :rows => 1
23 + -#%td.uinfo= in_place_editor_field :user, 'email_for_editing', {}, :rows => 1
25 %tr
24 %tr
26 %th.uinfo Password
25 %th.uinfo Password
27 %td.uinfo
26 %td.uinfo
28 - form_tag :action => 'chg_passwd', :method => 'post' do
27 - form_tag :action => 'chg_passwd', :method => 'post' do
29 %table
28 %table
30 %tr
29 %tr
31 %td= password_field_tag 'passwd'
30 %td= password_field_tag 'passwd'
32 %td (new)
31 %td (new)
33 %tr
32 %tr
34 %td= password_field_tag 'passwd_verify'
33 %td= password_field_tag 'passwd_verify'
35 %td (verify)
34 %td (verify)
36 %tr
35 %tr
37 %td{:colspan => "2"}
36 %td{:colspan => "2"}
38 = submit_tag 'change password'
37 = submit_tag 'change password'
39
38
@@ -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 %table
10 %table
6 - form_for :user, @user, :url => { :action => 'register' } do |f|
11 - form_for :user, @user, :url => { :action => 'register' } do |f|
7 %tr
12 %tr
8 - %td Login:
13 + %td{:align => "right"}
14 + = "#{t 'login_label'}:"
9 %td= f.text_field :login
15 %td= f.text_field :login
10 %tr
16 %tr
11 %td
17 %td
12 %td
18 %td
13 - %small Only a-z, A-Z, 0-9 and _
19 + %small
20 + =t 'registration.login_guide'
14 %tr
21 %tr
15 - %td Full name:
22 + %td{:align => "right"}
23 + = "#{t 'full_name_label'}:"
16 %td= f.text_field :full_name
24 %td= f.text_field :full_name
17 %tr
25 %tr
18 - %td E-mail:
26 + %td{:align => "right"}
27 + = "#{t 'email_label'}:"
19 %td= f.text_field :email
28 %td= f.text_field :email
20 %tr
29 %tr
21 %td
30 %td
22 %td
31 %td
23 %small
32 %small
24 - Please make sure that your e-mail is correct.
33 + =t 'registration.email_guide'
25 - %br/
26 - You'll need to verify your account by email.
27 %tr
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 %br/
5 %br/
5 - Please check at
6 + =t 'registration.email_verify_at', :email => @user.email
6 - = "#{@user.email}."
7 %br/
7 %br/
8 %br/
8 %br/
9
9
10 - Go back to
10 + =t 'go_back_to'
11 - = link_to 'login page.', :controller => 'main', :action => 'login'
11 + =link_to((t 'login_page'), {:controller => 'main', :action => 'login'})
@@ -1,77 +1,89
1 # Be sure to restart your web server when you modify this file.
1 # Be sure to restart your web server when you modify this file.
2
2
3 # Uncomment below to force Rails into production mode when
3 # Uncomment below to force Rails into production mode when
4 # you don't control web/app server and can't set it the proper way
4 # you don't control web/app server and can't set it the proper way
5 # ENV['RAILS_ENV'] ||= 'production'
5 # ENV['RAILS_ENV'] ||= 'production'
6
6
7 # Specifies gem version of Rails to use when vendor/rails is not present
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 # Bootstrap the Rails environment, frameworks, and default configuration
10 # Bootstrap the Rails environment, frameworks, and default configuration
11 require File.join(File.dirname(__FILE__), 'boot')
11 require File.join(File.dirname(__FILE__), 'boot')
12
12
13 Rails::Initializer.run do |config|
13 Rails::Initializer.run do |config|
14 # Settings in config/environments/* take precedence over those specified here
14 # Settings in config/environments/* take precedence over those specified here
15
15
16 # Skip frameworks you're not going to use (only works if using vendor/rails)
16 # Skip frameworks you're not going to use (only works if using vendor/rails)
17 # config.frameworks -= [ :action_web_service, :action_mailer ]
17 # config.frameworks -= [ :action_web_service, :action_mailer ]
18
18
19 # Only load the plugins named here, by default all plugins in vendor/plugins are loaded
19 # Only load the plugins named here, by default all plugins in vendor/plugins are loaded
20 # config.plugins = %W( exception_notification ssl_requirement )
20 # config.plugins = %W( exception_notification ssl_requirement )
21
21
22 # Add additional load paths for your own custom dirs
22 # Add additional load paths for your own custom dirs
23 # config.load_paths += %W( #{RAILS_ROOT}/extras )
23 # config.load_paths += %W( #{RAILS_ROOT}/extras )
24
24
25 # Force all environments to use the same logger level
25 # Force all environments to use the same logger level
26 # (by default production uses :info, the others :debug)
26 # (by default production uses :info, the others :debug)
27 # config.log_level = :debug
27 # config.log_level = :debug
28
28
29 # Use the database for sessions instead of the file system
29 # Use the database for sessions instead of the file system
30 # (create the session table with 'rake db:sessions:create')
30 # (create the session table with 'rake db:sessions:create')
31 config.action_controller.session_store = :active_record_store
31 config.action_controller.session_store = :active_record_store
32
32
33 # Use SQL instead of Active Record's schema dumper when creating the test database.
33 # Use SQL instead of Active Record's schema dumper when creating the test database.
34 # This is necessary if your schema can't be completely dumped by the schema dumper,
34 # This is necessary if your schema can't be completely dumped by the schema dumper,
35 # like if you have constraints or database-specific column types
35 # like if you have constraints or database-specific column types
36 # config.active_record.schema_format = :sql
36 # config.active_record.schema_format = :sql
37
37
38 # Activate observers that should always be running
38 # Activate observers that should always be running
39 # config.active_record.observers = :cacher, :garbage_collector
39 # config.active_record.observers = :cacher, :garbage_collector
40
40
41 # Make Active Record use UTC-base instead of local time
41 # Make Active Record use UTC-base instead of local time
42 - config.active_record.default_timezone = :utc
42 + config.time_zone = 'UTC'
43
43
44 + # Setting locales
45 + config.i18n.default_locale = 'th'
46 +
44 # See Rails::Configuration for more options
47 # See Rails::Configuration for more options
45
48
46 # -------------
49 # -------------
47 # Required gems
50 # Required gems
48 # -------------
51 # -------------
49 -
50 - # This is for rspec
51 - config.gem "rspec-rails", :lib => "spec"
52 config.gem "haml"
52 config.gem "haml"
53 config.gem "tmail"
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 end
59 end
56
60
57 # Add new inflection rules using the following format
61 # Add new inflection rules using the following format
58 # (all these examples are active by default):
62 # (all these examples are active by default):
59 # Inflector.inflections do |inflect|
63 # Inflector.inflections do |inflect|
60 # inflect.plural /^(ox)$/i, '\1en'
64 # inflect.plural /^(ox)$/i, '\1en'
61 # inflect.singular /^(ox)en/i, '\1'
65 # inflect.singular /^(ox)en/i, '\1'
62 # inflect.irregular 'person', 'people'
66 # inflect.irregular 'person', 'people'
63 # inflect.uncountable %w( fish sheep )
67 # inflect.uncountable %w( fish sheep )
64 # end
68 # end
65
69
66 # Add new mime types for use in respond_to blocks:
70 # Add new mime types for use in respond_to blocks:
67 # Mime::Type.register "text/richtext", :rtf
71 # Mime::Type.register "text/richtext", :rtf
68 # Mime::Type.register "application/x-mobile", :mobile
72 # Mime::Type.register "application/x-mobile", :mobile
69
73
70 # Include your application configuration below
74 # Include your application configuration below
71
75
72 # These are where inputs and outputs of test requests are stored
76 # These are where inputs and outputs of test requests are stored
73 TEST_REQUEST_INPUT_FILE_DIR = RAILS_ROOT + '/data/test_request/input'
77 TEST_REQUEST_INPUT_FILE_DIR = RAILS_ROOT + '/data/test_request/input'
74 TEST_REQUEST_OUTPUT_FILE_DIR = RAILS_ROOT + '/data/test_request/output'
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 # Uncomment so that configuration is read only once when the server is loaded
85 # Uncomment so that configuration is read only once when the server is loaded
77 # Configuration.enable_caching
86 # Configuration.enable_caching
87 +
88 + # Uncomment so that the system validates user e-mails
89 + # VALIDATE_USER_EMAILS = true
@@ -1,21 +1,20
1 # Settings specified here will take precedence over those in config/environment.rb
1 # Settings specified here will take precedence over those in config/environment.rb
2
2
3 # In the development environment your application's code is reloaded on
3 # In the development environment your application's code is reloaded on
4 # every request. This slows down response time but is perfect for development
4 # every request. This slows down response time but is perfect for development
5 # since you don't have to restart the webserver when you make code changes.
5 # since you don't have to restart the webserver when you make code changes.
6 config.cache_classes = false
6 config.cache_classes = false
7
7
8 # Log error messages when you accidentally call methods on nil.
8 # Log error messages when you accidentally call methods on nil.
9 config.whiny_nils = true
9 config.whiny_nils = true
10
10
11 # Enable the breakpoint server that script/breakpointer connects to
11 # Enable the breakpoint server that script/breakpointer connects to
12 #config.breakpoint_server = true
12 #config.breakpoint_server = true
13
13
14 # Show full error reports and disable caching
14 # Show full error reports and disable caching
15 config.action_controller.consider_all_requests_local = true
15 config.action_controller.consider_all_requests_local = true
16 config.action_controller.perform_caching = false
16 config.action_controller.perform_caching = false
17 - config.action_view.cache_template_extensions = false
18 config.action_view.debug_rjs = true
17 config.action_view.debug_rjs = true
19
18
20 # Don't care if the mailer can't send
19 # Don't care if the mailer can't send
21 config.action_mailer.raise_delivery_errors = false
20 config.action_mailer.raise_delivery_errors = false
@@ -1,19 +1,19
1 # Settings specified here will take precedence over those in config/environment.rb
1 # Settings specified here will take precedence over those in config/environment.rb
2
2
3 # The test environment is used exclusively to run your application's
3 # The test environment is used exclusively to run your application's
4 # test suite. You never need to work with it otherwise. Remember that
4 # test suite. You never need to work with it otherwise. Remember that
5 # your test database is "scratch space" for the test suite and is wiped
5 # your test database is "scratch space" for the test suite and is wiped
6 # and recreated between test runs. Don't rely on the data there!
6 # and recreated between test runs. Don't rely on the data there!
7 config.cache_classes = true
7 config.cache_classes = true
8
8
9 # Log error messages when you accidentally call methods on nil.
9 # Log error messages when you accidentally call methods on nil.
10 config.whiny_nils = true
10 config.whiny_nils = true
11
11
12 # Show full error reports and disable caching
12 # Show full error reports and disable caching
13 config.action_controller.consider_all_requests_local = true
13 config.action_controller.consider_all_requests_local = true
14 config.action_controller.perform_caching = false
14 config.action_controller.perform_caching = false
15
15
16 # Tell ActionMailer not to deliver emails to the real world.
16 # Tell ActionMailer not to deliver emails to the real world.
17 # The :test delivery method accumulates sent emails in the
17 # The :test delivery method accumulates sent emails in the
18 # ActionMailer::Base.deliveries array.
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
@@ -1,44 +1,45
1 # This file is auto-generated from the current state of the database. Instead of editing this file,
1 # This file is auto-generated from the current state of the database. Instead of editing this file,
2 # please use the migrations feature of Active Record to incrementally modify your database, and
2 # please use the migrations feature of Active Record to incrementally modify your database, and
3 # then regenerate this schema definition.
3 # then regenerate this schema definition.
4 #
4 #
5 # Note that this schema.rb definition is the authoritative source for your database schema. If you need
5 # Note that this schema.rb definition is the authoritative source for your database schema. If you need
6 # to create the application database on another system, you should be using db:schema:load, not running
6 # to create the application database on another system, you should be using db:schema:load, not running
7 # all the migrations from scratch. The latter is a flawed and unsustainable approach (the more migrations
7 # all the migrations from scratch. The latter is a flawed and unsustainable approach (the more migrations
8 # you'll amass, the slower it'll run and the greater likelihood for issues).
8 # you'll amass, the slower it'll run and the greater likelihood for issues).
9 #
9 #
10 # It's strongly recommended to check this file into your version control system.
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 create_table "announcements", :force => true do |t|
14 create_table "announcements", :force => true do |t|
15 t.string "author"
15 t.string "author"
16 t.text "body"
16 t.text "body"
17 t.boolean "published"
17 t.boolean "published"
18 t.datetime "created_at"
18 t.datetime "created_at"
19 t.datetime "updated_at"
19 t.datetime "updated_at"
20 - t.boolean "frontpage", :default => false
20 + t.boolean "frontpage", :default => false
21 + t.boolean "contest_only", :default => false
21 end
22 end
22
23
23 create_table "configurations", :force => true do |t|
24 create_table "configurations", :force => true do |t|
24 t.string "key"
25 t.string "key"
25 t.string "value_type"
26 t.string "value_type"
26 t.string "value"
27 t.string "value"
27 t.datetime "created_at"
28 t.datetime "created_at"
28 t.datetime "updated_at"
29 t.datetime "updated_at"
29 end
30 end
30
31
31 create_table "countries", :force => true do |t|
32 create_table "countries", :force => true do |t|
32 t.string "name"
33 t.string "name"
33 t.datetime "created_at"
34 t.datetime "created_at"
34 t.datetime "updated_at"
35 t.datetime "updated_at"
35 end
36 end
36
37
37 create_table "descriptions", :force => true do |t|
38 create_table "descriptions", :force => true do |t|
38 t.text "body"
39 t.text "body"
39 t.boolean "markdowned"
40 t.boolean "markdowned"
40 t.datetime "created_at"
41 t.datetime "created_at"
41 t.datetime "updated_at"
42 t.datetime "updated_at"
42 end
43 end
43
44
44 create_table "grader_processes", :force => true do |t|
45 create_table "grader_processes", :force => true do |t|
@@ -153,40 +154,40
153
154
154 create_table "test_requests", :force => true do |t|
155 create_table "test_requests", :force => true do |t|
155 t.integer "user_id"
156 t.integer "user_id"
156 t.integer "problem_id"
157 t.integer "problem_id"
157 t.integer "submission_id"
158 t.integer "submission_id"
158 t.string "input_file_name"
159 t.string "input_file_name"
159 t.string "output_file_name"
160 t.string "output_file_name"
160 t.string "running_stat"
161 t.string "running_stat"
161 t.integer "status"
162 t.integer "status"
162 t.datetime "updated_at"
163 t.datetime "updated_at"
163 t.datetime "submitted_at"
164 t.datetime "submitted_at"
164 t.datetime "compiled_at"
165 t.datetime "compiled_at"
165 t.text "compiler_message"
166 t.text "compiler_message"
166 t.datetime "graded_at"
167 t.datetime "graded_at"
167 t.string "grader_comment"
168 t.string "grader_comment"
168 t.datetime "created_at"
169 t.datetime "created_at"
169 t.float "running_time"
170 t.float "running_time"
170 t.string "exit_status"
171 t.string "exit_status"
171 t.integer "memory_usage"
172 t.integer "memory_usage"
172 end
173 end
173
174
174 add_index "test_requests", ["user_id", "problem_id"], :name => "index_test_requests_on_user_id_and_problem_id"
175 add_index "test_requests", ["user_id", "problem_id"], :name => "index_test_requests_on_user_id_and_problem_id"
175
176
176 create_table "users", :force => true do |t|
177 create_table "users", :force => true do |t|
177 - t.string "login", :limit => 10
178 + t.string "login", :limit => 50
178 t.string "full_name"
179 t.string "full_name"
179 t.string "hashed_password"
180 t.string "hashed_password"
180 t.string "salt", :limit => 5
181 t.string "salt", :limit => 5
181 t.string "alias"
182 t.string "alias"
182 t.string "email"
183 t.string "email"
183 t.integer "site_id"
184 t.integer "site_id"
184 t.integer "country_id"
185 t.integer "country_id"
185 t.boolean "activated", :default => false
186 t.boolean "activated", :default => false
186 t.datetime "created_at"
187 t.datetime "created_at"
187 t.datetime "updated_at"
188 t.datetime "updated_at"
188 end
189 end
189
190
190 add_index "users", ["login"], :name => "index_users_on_login", :unique => true
191 add_index "users", ["login"], :name => "index_users_on_login", :unique => true
191
192
192 end
193 end
@@ -1,27 +1,28
1 /* Normal text */
1 /* Normal text */
2 - p {
2 + body {
3 - font-size: 12px;
3 + font-size: 13px;
4 + font-family: "Sans Serif";
4 }
5 }
5
6
6 /* This is the main menu bad*/
7 /* This is the main menu bad*/
7 div.userbar {
8 div.userbar {
8 border-top: thin solid grey;
9 border-top: thin solid grey;
9 border-bottom: thin solid grey;
10 border-bottom: thin solid grey;
10 text-align: right;
11 text-align: right;
11 font-size: 12px;
12 font-size: 12px;
12 }
13 }
13
14
14 /* This is the top bar, displaying user's full name */
15 /* This is the top bar, displaying user's full name */
15 div.title {
16 div.title {
16 font-size: 12px;
17 font-size: 12px;
17 background: #ddffdd;
18 background: #ddffdd;
18 border: 1px solid black;
19 border: 1px solid black;
19 padding: 2px;
20 padding: 2px;
20 margin-top: 3px;
21 margin-top: 3px;
21 margin-bottom: 5px;
22 margin-bottom: 5px;
22 }
23 }
23
24
24 div.title span.contest-over-msg {
25 div.title span.contest-over-msg {
25 font-size: 15px;
26 font-size: 15px;
26 color: red;
27 color: red;
27 font-weight: bold;
28 font-weight: bold;
@@ -206,24 +207,54
206
207
207 div.message {
208 div.message {
208 padding-top: 5px;
209 padding-top: 5px;
209 padding-left: 10px;
210 padding-left: 10px;
210 }
211 }
211
212
212 div.message div.body {
213 div.message div.body {
213 border: 1px solid green;
214 border: 1px solid green;
214 background: #eeffee;
215 background: #eeffee;
215 padding-left: 5px;
216 padding-left: 5px;
216 }
217 }
217
218
218 div.message div.reply-body {
219 div.message div.reply-body {
219 border: 1px solid black;
220 border: 1px solid black;
220 background: #ffeeee;
221 background: #ffeeee;
221 padding-left: 5px;
222 padding-left: 5px;
222 }
223 }
223
224
224 div.message div.stat {
225 div.message div.stat {
225 font-size: 10px;
226 font-size: 10px;
226 color: white;
227 color: white;
227 background: green;
228 background: green;
228 font-weight: bold;
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