Description:
sends notification emails to users after contest upgrade.
Commit status:
[Not Reviewed]
References:
Comments:
0 Commit comments 0 Inline Comments
Unresolved TODOs:
There are no unresolved TODOs
Add another comment

r296:3e5af2413b70 - - 8 files changed: 143 inserted, 62 deleted

@@ -0,0 +1,36
1 + module MailHelperMethods
2 +
3 + def send_mail(to, subject, body)
4 + mail = TMail::Mail.new
5 + mail.to = to
6 + mail.from = Configuration['system.online_registration.from']
7 + mail.subject = subject
8 + mail.body = body
9 +
10 + smtp_server = Configuration['system.online_registration.smtp']
11 +
12 + if ['fake', 'debug'].include? smtp_server
13 + puts "-------------------------
14 + To: #{mail.to}
15 + From: #{mail.from}
16 + Subject: #{mail.subject}
17 + #{mail.body}
18 + --------------------------
19 + "
20 + return true
21 + end
22 +
23 + begin
24 + Net::SMTP.start(smtp_server) do |smtp|
25 + smtp.send_message(mail.to_s, mail.from, mail.to)
26 + end
27 + result = true
28 + rescue
29 + result = false
30 + end
31 +
32 + result
33 + end
34 +
35 + end
36 +
@@ -20,48 +20,49
20 return false
20 return false
21 end
21 end
22 end
22 end
23
23
24 protected
24 protected
25
25
26 def authenticate
26 def authenticate
27 unless session[:user_id]
27 unless session[:user_id]
28 redirect_to :controller => 'main', :action => 'login'
28 redirect_to :controller => 'main', :action => 'login'
29 return false
29 return false
30 end
30 end
31
31
32 # check if run in single user mode
32 # check if run in single user mode
33 if Configuration[SINGLE_USER_MODE_CONF_KEY]
33 if Configuration[SINGLE_USER_MODE_CONF_KEY]
34 user = User.find(session[:user_id])
34 user = User.find(session[:user_id])
35 if user==nil or (not user.admin?)
35 if user==nil or (not user.admin?)
36 redirect_to :controller => 'main', :action => 'login'
36 redirect_to :controller => 'main', :action => 'login'
37 return false
37 return false
38 end
38 end
39 return true
39 return true
40 end
40 end
41
41
42 if Configuration.multicontests?
42 if Configuration.multicontests?
43 user = User.find(session[:user_id])
43 user = User.find(session[:user_id])
44 + return true if user.admin?
44 begin
45 begin
45 if user.contest_stat(true).forced_logout
46 if user.contest_stat(true).forced_logout
46 flash[:notice] = 'You have been automatically logged out.'
47 flash[:notice] = 'You have been automatically logged out.'
47 redirect_to :controller => 'main', :action => 'index'
48 redirect_to :controller => 'main', :action => 'index'
48 end
49 end
49 rescue
50 rescue
50 end
51 end
51 end
52 end
52 return true
53 return true
53 end
54 end
54
55
55 def authorization
56 def authorization
56 return false unless authenticate
57 return false unless authenticate
57 user = User.find(session[:user_id])
58 user = User.find(session[:user_id])
58 unless user.roles.detect { |role|
59 unless user.roles.detect { |role|
59 role.rights.detect{ |right|
60 role.rights.detect{ |right|
60 right.controller == self.class.controller_name and
61 right.controller == self.class.controller_name and
61 (right.action == 'all' or right.action == action_name)
62 (right.action == 'all' or right.action == action_name)
62 }
63 }
63 }
64 }
64 flash[:notice] = 'You are not authorized to view the page you requested'
65 flash[:notice] = 'You are not authorized to view the page you requested'
65 #request.env['HTTP_REFERER'] ? (redirect_to :back) : (redirect_to :controller => 'login')
66 #request.env['HTTP_REFERER'] ? (redirect_to :back) : (redirect_to :controller => 'login')
66 redirect_to :controller => 'main', :action => 'login'
67 redirect_to :controller => 'main', :action => 'login'
67 return false
68 return false
@@ -1,26 +1,28
1 class UserAdminController < ApplicationController
1 class UserAdminController < ApplicationController
2
2
3 + include MailHelperMethods
4 +
3 before_filter :admin_authorization
5 before_filter :admin_authorization
4
6
5 def index
7 def index
6 list
8 list
7 render :action => 'list'
9 render :action => 'list'
8 end
10 end
9
11
10 # GETs should be safe (see http://www.w3.org/2001/tag/doc/whenToUseGet.html)
12 # GETs should be safe (see http://www.w3.org/2001/tag/doc/whenToUseGet.html)
11 verify :method => :post, :only => [ :destroy,
13 verify :method => :post, :only => [ :destroy,
12 :create, :create_from_list,
14 :create, :create_from_list,
13 :update ],
15 :update ],
14 :redirect_to => { :action => :list }
16 :redirect_to => { :action => :list }
15
17
16 def list
18 def list
17 @users = User.find(:all)
19 @users = User.find(:all)
18 @hidden_columns = ['hashed_password', 'salt', 'created_at', 'updated_at']
20 @hidden_columns = ['hashed_password', 'salt', 'created_at', 'updated_at']
19 @contests = Contest.all(:conditions => {:enabled => true})
21 @contests = Contest.all(:conditions => {:enabled => true})
20 end
22 end
21
23
22 def active
24 def active
23 sessions = ActiveRecord::SessionStore::Session.find(:all, :conditions => ["updated_at >= ?", 60.minutes.ago])
25 sessions = ActiveRecord::SessionStore::Session.find(:all, :conditions => ["updated_at >= ?", 60.minutes.ago])
24 @users = []
26 @users = []
25 sessions.each do |session|
27 sessions.each do |session|
26 if session.data[:user_id]
28 if session.data[:user_id]
@@ -194,48 +196,52
194 flash[:notice] = 'You entered an empty list.'
196 flash[:notice] = 'You entered an empty list.'
195 redirect_to :action => 'contest_management' and return
197 redirect_to :action => 'contest_management' and return
196 end
198 end
197
199
198 note = []
200 note = []
199 users = []
201 users = []
200 lines.split("\n").each do |line|
202 lines.split("\n").each do |line|
201 user = User.find_by_login(line.chomp)
203 user = User.find_by_login(line.chomp)
202 if user
204 if user
203 if operation=='add'
205 if operation=='add'
204 if ! user.contests.include? contest
206 if ! user.contests.include? contest
205 user.contests << contest
207 user.contests << contest
206 end
208 end
207 elsif operation=='remove'
209 elsif operation=='remove'
208 user.contests.delete(contest)
210 user.contests.delete(contest)
209 else
211 else
210 user.contests = [contest]
212 user.contests = [contest]
211 end
213 end
212
214
213 if params[:reset_timer]
215 if params[:reset_timer]
214 user.contest_stat.forced_logout = true
216 user.contest_stat.forced_logout = true
215 user.contest_stat.reset_timer_and_save
217 user.contest_stat.reset_timer_and_save
216 end
218 end
217
219
220 + if params[:notification_emails]
221 + send_contest_update_notification_email(user, contest)
222 + end
223 +
218 note << user.login
224 note << user.login
219 users << user
225 users << user
220 end
226 end
221 end
227 end
222
228
223 if params[:reset_timer]
229 if params[:reset_timer]
224 logout_users(users)
230 logout_users(users)
225 end
231 end
226
232
227 flash[:notice] = 'User(s) ' + note.join(', ') +
233 flash[:notice] = 'User(s) ' + note.join(', ') +
228 ' were successfully modified. '
234 ' were successfully modified. '
229 redirect_to :action => 'contest_management'
235 redirect_to :action => 'contest_management'
230 end
236 end
231
237
232 # admin management
238 # admin management
233
239
234 def admin
240 def admin
235 @admins = User.find(:all).find_all {|user| user.admin? }
241 @admins = User.find(:all).find_all {|user| user.admin? }
236 end
242 end
237
243
238 def grant_admin
244 def grant_admin
239 login = params[:login]
245 login = params[:login]
240 user = User.find_by_login(login)
246 user = User.find_by_login(login)
241 if user!=nil
247 if user!=nil
@@ -323,25 +329,40
323 u.full_name = user[:name]
329 u.full_name = user[:name]
324 u.password = user[:password]
330 u.password = user[:password]
325 u.country = countries[user[:country_id]]
331 u.country = countries[user[:country_id]]
326 u.site = sites[user[:site_id]]
332 u.site = sites[user[:site_id]]
327 u.activated = true
333 u.activated = true
328 u.email = "empty-#{u.login}@none.com"
334 u.email = "empty-#{u.login}@none.com"
329 if not u.save
335 if not u.save
330 @import_log << "Errors\n"
336 @import_log << "Errors\n"
331 u.errors.each { |attr,msg| @import_log << "#{attr} - #{msg}\n" }
337 u.errors.each { |attr,msg| @import_log << "#{attr} - #{msg}\n" }
332 end
338 end
333 end
339 end
334
340
335 end
341 end
336
342
337 def logout_users(users)
343 def logout_users(users)
338 users.each do |user|
344 users.each do |user|
339 contest_stat = user.contest_stat(true)
345 contest_stat = user.contest_stat(true)
340 if contest_stat and !contest_stat.forced_logout
346 if contest_stat and !contest_stat.forced_logout
341 contest_stat.forced_logout = true
347 contest_stat.forced_logout = true
342 contest_stat.save
348 contest_stat.save
343 end
349 end
344 end
350 end
345 end
351 end
346
352
353 + def send_contest_update_notification_email(user, contest)
354 + contest_title_name = Configuration['contest.name']
355 + contest_name = contest.name
356 + subject = t('contest.notification.email_subject', {
357 + :contest_title_name => contest_title_name,
358 + :contest_name => contest_name })
359 + body = t('contest.notification.email_body', {
360 + :full_name => user.full_name,
361 + :contest_title_name => contest_title_name,
362 + :contest_name => contest.name,
363 + })
364 +
365 + logger.info body
366 + send_mail(user.email, subject, body)
347 end
367 end
368 + end
@@ -1,29 +1,31
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 + include MailHelperMethods
7 +
6 before_filter :authenticate, :except => [:new,
8 before_filter :authenticate, :except => [:new,
7 :register,
9 :register,
8 :confirm,
10 :confirm,
9 :forget,
11 :forget,
10 :retrieve_password]
12 :retrieve_password]
11
13
12 before_filter :verify_online_registration, :only => [:new,
14 before_filter :verify_online_registration, :only => [:new,
13 :register,
15 :register,
14 :forget,
16 :forget,
15 :retrieve_password]
17 :retrieve_password]
16
18
17 verify :method => :post, :only => [:chg_passwd],
19 verify :method => :post, :only => [:chg_passwd],
18 :redirect_to => { :action => :index }
20 :redirect_to => { :action => :index }
19
21
20 #in_place_edit_for :user, :alias_for_editing
22 #in_place_edit_for :user, :alias_for_editing
21 #in_place_edit_for :user, :email_for_editing
23 #in_place_edit_for :user, :email_for_editing
22
24
23 def index
25 def index
24 if !Configuration['system.user_setting_enabled']
26 if !Configuration['system.user_setting_enabled']
25 redirect_to :controller => 'main', :action => 'list'
27 redirect_to :controller => 'main', :action => 'list'
26 else
28 else
27 @user = User.find(session[:user_id])
29 @user = User.find(session[:user_id])
28 end
30 end
29 end
31 end
@@ -101,85 +103,56
101 send_new_password_email(user)
103 send_new_password_email(user)
102 flash[:notice] = 'New password has been mailed to you.'
104 flash[:notice] = 'New password has been mailed to you.'
103 end
105 end
104 else
106 else
105 flash[:notice] = I18n.t 'registration.password_retrieval.no_email'
107 flash[:notice] = I18n.t 'registration.password_retrieval.no_email'
106 end
108 end
107 redirect_to :action => 'forget'
109 redirect_to :action => 'forget'
108 end
110 end
109
111
110 protected
112 protected
111
113
112 def verify_online_registration
114 def verify_online_registration
113 if !Configuration['system.online_registration']
115 if !Configuration['system.online_registration']
114 redirect_to :controller => 'main', :action => 'login'
116 redirect_to :controller => 'main', :action => 'login'
115 end
117 end
116 end
118 end
117
119
118 def send_confirmation_email(user)
120 def send_confirmation_email(user)
119 contest_name = Configuration['contest.name']
121 contest_name = Configuration['contest.name']
120 admin_email = Configuration['system.admin_email']
122 admin_email = Configuration['system.admin_email']
121 activation_url = url_for(:action => 'confirm',
123 activation_url = url_for(:action => 'confirm',
122 :login => user.login,
124 :login => user.login,
123 :activation => user.activation_key)
125 :activation => user.activation_key)
124 home_url = url_for(:controller => 'main', :action => 'index')
126 home_url = url_for(:controller => 'main', :action => 'index')
125 - mail = TMail::Mail.new
127 + subject = "[#{contest_name}] Confirmation"
126 - mail.to = user.email
128 + body = t('registration.email_body', {
127 - mail.from = Configuration['system.online_registration.from']
128 - mail.subject = "[#{contest_name}] Confirmation"
129 - mail.body = t('registration.email_body', {
130 :full_name => user.full_name,
129 :full_name => user.full_name,
131 :contest_name => contest_name,
130 :contest_name => contest_name,
132 :login => user.login,
131 :login => user.login,
133 :password => user.password,
132 :password => user.password,
134 :activation_url => activation_url,
133 :activation_url => activation_url,
135 :admin_email => admin_email
134 :admin_email => admin_email
136 })
135 })
137
136
138 - logger.info mail.body
137 + logger.info body
139 -
140 - smtp_server = Configuration['system.online_registration.smtp']
141
138
142 - begin
139 + send_mail(user.email, subject, body)
143 - Net::SMTP.start(smtp_server) do |smtp|
144 - smtp.send_message(mail.to_s, mail.from, mail.to)
145 - end
146 - result = true
147 - rescue
148 - result = false
149 - end
150 -
151 - return result
152 end
140 end
153
141
154 def send_new_password_email(user)
142 def send_new_password_email(user)
155 contest_name = Configuration['contest.name']
143 contest_name = Configuration['contest.name']
156 admin_email = Configuration['system.admin_email']
144 admin_email = Configuration['system.admin_email']
157 - mail = TMail::Mail.new
145 + subject = "[#{contest_name}] Password recovery"
158 - mail.to = user.email
146 + body = t('registration.password_retrieval.email_body', {
159 - mail.from = Configuration['system.online_registration.from']
160 - mail.subject = "[#{contest_name}] Password recovery"
161 - mail.body = t('registration.password_retrieval.email_body', {
162 :full_name => user.full_name,
147 :full_name => user.full_name,
163 :contest_name => contest_name,
148 :contest_name => contest_name,
164 :login => user.login,
149 :login => user.login,
165 :password => user.password,
150 :password => user.password,
166 :admin_email => admin_email
151 :admin_email => admin_email
167 })
152 })
168
153
169 - logger.info mail.body
154 + logger.info body
170 -
155 + send_mail(user.email, subject, body)
171 - smtp_server = Configuration['system.online_registration.smtp']
172 -
173 - begin
174 - Net::SMTP.start(smtp_server) do |smtp|
175 - smtp.send_message(mail.to_s, mail.from, mail.to)
176 - end
177 - result = true
178 - rescue
179 - result = false
180 - end
181 -
182 - return result
183 end
156 end
184
157
185 end
158 end
@@ -1,19 +1,26
1 %h1 Bulk edit users in contests
1 %h1 Bulk edit users in contests
2
2
3 - form_tag :action => 'manage_contest' do
3 - form_tag :action => 'manage_contest' do
4 List users' login below; one per line.
4 List users' login below; one per line.
5 %br/
5 %br/
6 = text_area_tag 'login_list', nil, :rows => 23, :cols => 80
6 = text_area_tag 'login_list', nil, :rows => 23, :cols => 80
7 %br/
7 %br/
8 + %table
9 + %tr
10 + %td{:valign => 'top'}
8 You want to
11 You want to
9 = select(nil,"operation",[['assign users to','assign'],['add users to','add'],['remove users from','remove']])
12 = select(nil,"operation",[['assign users to','assign'],['add users to','add'],['remove users from','remove']])
10 contest
13 contest
11 = select("contest","id",Contest.all.collect {|c| [c.title, c.id]})
14 = select("contest","id",Contest.all.collect {|c| [c.title, c.id]})
15 + and also
16 + %td
12 = check_box_tag 'reset_timer'
17 = check_box_tag 'reset_timer'
13 Auto-reset current contest timer.
18 Auto-reset current contest timer.
14 %br/
19 %br/
20 + = check_box_tag 'notification_emails'
21 + Send notification email(s).
15
22
16 = submit_tag "Perform action!", :confirm => 'Are you sure?'
23 = submit_tag "Perform action!", :confirm => 'Are you sure?'
17
24
18 %hr/
25 %hr/
19 = link_to '[go back to index]', :action => 'index'
26 = link_to '[go back to index]', :action => 'index'
@@ -98,42 +98,54
98 title: "Errors in sending registration confirmation"
98 title: "Errors in sending registration confirmation"
99 expl: "<h2>Your user account has been created, but the system cannot send you the confirmation e-mail.</h2>
99 expl: "<h2>Your user account has been created, but the system cannot send you the confirmation e-mail.</h2>
100 Maybe there's a problem in the configuration. Please report the admin at {{email}}.<br/>Thank you!"
100 Maybe there's a problem in the configuration. Please report the admin at {{email}}.<br/>Thank you!"
101 activation:
101 activation:
102 email_exists: "A user with this E-mail exists."
102 email_exists: "A user with this E-mail exists."
103 invalid: "Your activation code is invalid. Please check again."
103 invalid: "Your activation code is invalid. Please check again."
104
104
105 password_retrieval:
105 password_retrieval:
106 header: "Password retrieval"
106 header: "Password retrieval"
107 instructions: "Please enter the e-mail address that you used to register."
107 instructions: "Please enter the e-mail address that you used to register."
108 button_label: "Request new password"
108 button_label: "Request new password"
109 no_email: "No user with that e-mail address."
109 no_email: "No user with that e-mail address."
110 email_body: "Hello {{full_name}},
110 email_body: "Hello {{full_name}},
111
111
112 You have requested for new password for {{contest_name}}. We have generated it for you:
112 You have requested for new password for {{contest_name}}. We have generated it for you:
113
113
114 user name: {{login}}
114 user name: {{login}}
115 password: {{password}}
115 password: {{password}}
116
116
117 If you didn't ask for new password or you're not the person who registered,
117 If you didn't ask for new password or you're not the person who registered,
118 please ignore this e-mail and inform {{admin_email}} of this mistake.
118 please ignore this e-mail and inform {{admin_email}} of this mistake.
119
119
120 Thanks!"
120 Thanks!"
121
121
122 + contest:
123 + notification:
124 + email_subject: "[{{contest_title_name}}] You have been upgraded to {{contest_name}}"
125 + email_body: "Congratulations {{full_name}},
126 +
127 + You have advanced to contest {{contest_name}} in {{contest_title_name}}.
128 +
129 + You can now log-in and start participating in that contest.
130 +
131 + Cheers!
132 + -{{contest_title_name}} Admin"
133 +
122 help:
134 help:
123 how_to_submit: "How to submit"
135 how_to_submit: "How to submit"
124 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."
136 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."
125 list_available_language: "The possible language options are <tt>C</tt>, <tt>C++</tt>, and <tt>Pascal</tt>. The follow are examples."
137 list_available_language: "The possible language options are <tt>C</tt>, <tt>C++</tt>, and <tt>Pascal</tt>. The follow are examples."
126 accept_only_language_specified: "The server <b>will not</b> accept your submission, if you do not specify the language."
138 accept_only_language_specified: "The server <b>will not</b> accept your submission, if you do not specify the language."
127 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."
139 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."
128 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."
140 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."
129 example_pas: "If you are using <tt>Pascal</tt> to write the same task, you'll use"
141 example_pas: "If you are using <tt>Pascal</tt> to write the same task, you'll use"
130 ask_questions_at_messages: "If you have any problems, you can ask at [<a href=\"{{url}}\">{{message_link_name}}</a>]."
142 ask_questions_at_messages: "If you have any problems, you can ask at [<a href=\"{{url}}\">{{message_link_name}}</a>]."
131
143
132 activerecord:
144 activerecord:
133 attributes:
145 attributes:
134 user:
146 user:
135 login: "login"
147 login: "login"
136 full_name: "full name"
148 full_name: "full name"
137 email: "e-mail"
149 email: "e-mail"
138 province: "province"
150 province: "province"
139
151
@@ -57,82 +57,94
57 registration:
57 registration:
58 title: "ΰΈ₯ΰΈ‡ΰΈ—ΰΈ°ΰΉ€ΰΈšΰΈ΅ΰΈ’ΰΈ™ΰΈœΰΈΉΰΉ‰ΰΉƒΰΈŠΰΉ‰ΰΉƒΰΈ«ΰΈ‘ΰΉˆ"
58 title: "ΰΈ₯ΰΈ‡ΰΈ—ΰΈ°ΰΉ€ΰΈšΰΈ΅ΰΈ’ΰΈ™ΰΈœΰΈΉΰΉ‰ΰΉƒΰΈŠΰΉ‰ΰΉƒΰΈ«ΰΈ‘ΰΉˆ"
59 description: "ในการΰΈ₯ΰΈ‡ΰΈ—ΰΈ°ΰΉ€ΰΈšΰΈ΅ΰΈ’ΰΈ™ ΰΉƒΰΈ«ΰΉ‰ΰΈœΰΈΉΰΉ‰ΰΈͺΰΈ™ΰΉƒΰΈˆΰΉ€ΰΈ‚ΰΉ‰ΰΈ²ΰΈ£ΰΉˆΰΈ§ΰΈ‘ΰΈΰΈ²ΰΈ£ΰΉΰΈ‚ΰΉˆΰΈ‡ΰΈ‚ΰΈ±ΰΈ™ΰΈΰΈ£ΰΈ­ΰΈΰΈ‚ΰΉ‰ΰΈ­ΰΈ‘ΰΈΉΰΈ₯ΰΈ”ΰΉ‰ΰΈ²ΰΈ™ΰΈ₯ΰΉˆΰΈ²ΰΈ‡ ΰΈˆΰΈ²ΰΈΰΈ™ΰΈ±ΰΉ‰ΰΈ™ΰΈ£ΰΈ°ΰΈšΰΈšΰΈˆΰΈ°ΰΈͺΰΉˆΰΈ‡ e-mail ΰΉ„ΰΈ›ΰΈ’ΰΈ±ΰΈ‡ e-mail ΰΈ—ΰΈ΅ΰΉˆΰΈ£ΰΈ°ΰΈšΰΈΈΰΉ€ΰΈžΰΈ·ΰΉˆΰΈ­ΰΉƒΰΈ«ΰΉ‰ΰΈ’ΰΈ·ΰΈ™ΰΈ’ΰΈ±ΰΈ™ΰΈ•ΰΈ±ΰΈ§ΰΈ•ΰΈ™ΰΉΰΈ₯ΰΈ°ΰΉ€ΰΈ›ΰΈ΄ΰΈ”ΰΉƒΰΈŠΰΉ‰ΰΈšΰΈ±ΰΈΰΈŠΰΈ΅ΰΈœΰΈΉΰΉ‰ΰΉƒΰΈŠΰΉ‰<br/>ΰΉƒΰΈ™ΰΈΰΈ£ΰΈ“ΰΈ΅ΰΈ—ΰΈ΅ΰΉˆΰΈœΰΈΉΰΉ‰ΰΉ€ΰΈ‚ΰΉ‰ΰΈ²ΰΉΰΈ‚ΰΉˆΰΈ‡ΰΈ‚ΰΈ±ΰΈ™ΰΉ€ΰΈ›ΰΉ‡ΰΈ™ΰΈ™ΰΈ±ΰΈΰΉ€ΰΈ£ΰΈ΅ΰΈ’ΰΈ™ ΰΈ£ΰΈšΰΈΰΈ§ΰΈ™ΰΈŠΰΉˆΰΈ§ΰΈ’ΰΉƒΰΈ«ΰΉ‰ΰΈ‚ΰΉ‰ΰΈ­ΰΈ‘ΰΈΉΰΈ₯ΰΉ€ΰΈΰΈ΅ΰΉˆΰΈ’ΰΈ§ΰΈΰΈ±ΰΈšΰΉ‚ΰΈ£ΰΈ‡ΰΉ€ΰΈ£ΰΈ΅ΰΈ’ΰΈ™ΰΉΰΈ₯ΰΈ°ΰΈˆΰΈ±ΰΈ‡ΰΈ«ΰΈ§ΰΈ±ΰΈ”ΰΈ”ΰΉ‰ΰΈ§ΰΈ’"
59 description: "ในการΰΈ₯ΰΈ‡ΰΈ—ΰΈ°ΰΉ€ΰΈšΰΈ΅ΰΈ’ΰΈ™ ΰΉƒΰΈ«ΰΉ‰ΰΈœΰΈΉΰΉ‰ΰΈͺΰΈ™ΰΉƒΰΈˆΰΉ€ΰΈ‚ΰΉ‰ΰΈ²ΰΈ£ΰΉˆΰΈ§ΰΈ‘ΰΈΰΈ²ΰΈ£ΰΉΰΈ‚ΰΉˆΰΈ‡ΰΈ‚ΰΈ±ΰΈ™ΰΈΰΈ£ΰΈ­ΰΈΰΈ‚ΰΉ‰ΰΈ­ΰΈ‘ΰΈΉΰΈ₯ΰΈ”ΰΉ‰ΰΈ²ΰΈ™ΰΈ₯ΰΉˆΰΈ²ΰΈ‡ ΰΈˆΰΈ²ΰΈΰΈ™ΰΈ±ΰΉ‰ΰΈ™ΰΈ£ΰΈ°ΰΈšΰΈšΰΈˆΰΈ°ΰΈͺΰΉˆΰΈ‡ e-mail ΰΉ„ΰΈ›ΰΈ’ΰΈ±ΰΈ‡ e-mail ΰΈ—ΰΈ΅ΰΉˆΰΈ£ΰΈ°ΰΈšΰΈΈΰΉ€ΰΈžΰΈ·ΰΉˆΰΈ­ΰΉƒΰΈ«ΰΉ‰ΰΈ’ΰΈ·ΰΈ™ΰΈ’ΰΈ±ΰΈ™ΰΈ•ΰΈ±ΰΈ§ΰΈ•ΰΈ™ΰΉΰΈ₯ΰΈ°ΰΉ€ΰΈ›ΰΈ΄ΰΈ”ΰΉƒΰΈŠΰΉ‰ΰΈšΰΈ±ΰΈΰΈŠΰΈ΅ΰΈœΰΈΉΰΉ‰ΰΉƒΰΈŠΰΉ‰<br/>ΰΉƒΰΈ™ΰΈΰΈ£ΰΈ“ΰΈ΅ΰΈ—ΰΈ΅ΰΉˆΰΈœΰΈΉΰΉ‰ΰΉ€ΰΈ‚ΰΉ‰ΰΈ²ΰΉΰΈ‚ΰΉˆΰΈ‡ΰΈ‚ΰΈ±ΰΈ™ΰΉ€ΰΈ›ΰΉ‡ΰΈ™ΰΈ™ΰΈ±ΰΈΰΉ€ΰΈ£ΰΈ΅ΰΈ’ΰΈ™ ΰΈ£ΰΈšΰΈΰΈ§ΰΈ™ΰΈŠΰΉˆΰΈ§ΰΈ’ΰΉƒΰΈ«ΰΉ‰ΰΈ‚ΰΉ‰ΰΈ­ΰΈ‘ΰΈΉΰΈ₯ΰΉ€ΰΈΰΈ΅ΰΉˆΰΈ’ΰΈ§ΰΈΰΈ±ΰΈšΰΉ‚ΰΈ£ΰΈ‡ΰΉ€ΰΈ£ΰΈ΅ΰΈ’ΰΈ™ΰΉΰΈ₯ΰΈ°ΰΈˆΰΈ±ΰΈ‡ΰΈ«ΰΈ§ΰΈ±ΰΈ”ΰΈ”ΰΉ‰ΰΈ§ΰΈ’"
60
60
61 successful_title: "การΰΈ₯ΰΈ‡ΰΈ—ΰΈ°ΰΉ€ΰΈšΰΈ΅ΰΈ’ΰΈ™ΰΉ€ΰΈͺΰΈ£ΰΉ‡ΰΈˆΰΉ€ΰΈ£ΰΈ΅ΰΈ’ΰΈšΰΈ£ΰΉ‰ΰΈ­ΰΈ’"
61 successful_title: "การΰΈ₯ΰΈ‡ΰΈ—ΰΈ°ΰΉ€ΰΈšΰΈ΅ΰΈ’ΰΈ™ΰΉ€ΰΈͺΰΈ£ΰΉ‡ΰΈˆΰΉ€ΰΈ£ΰΈ΅ΰΈ’ΰΈšΰΈ£ΰΉ‰ΰΈ­ΰΈ’"
62
62
63 login_guide: "ΰΉƒΰΈŠΰΉ‰ΰΉ„ΰΈ”ΰΉ‰ΰΉ€ΰΈ‰ΰΈžΰΈ²ΰΈ° a-z, A-Z, 0-9 แΰΈ₯ΰΈ° _ ΰΈ„ΰΈ§ΰΈ²ΰΈ‘ΰΈ’ΰΈ²ΰΈ§ΰΉ„ΰΈ‘ΰΉˆΰΉ€ΰΈΰΈ΄ΰΈ™ 20 ตัวอักษร"
63 login_guide: "ΰΉƒΰΈŠΰΉ‰ΰΉ„ΰΈ”ΰΉ‰ΰΉ€ΰΈ‰ΰΈžΰΈ²ΰΈ° a-z, A-Z, 0-9 แΰΈ₯ΰΈ° _ ΰΈ„ΰΈ§ΰΈ²ΰΈ‘ΰΈ’ΰΈ²ΰΈ§ΰΉ„ΰΈ‘ΰΉˆΰΉ€ΰΈΰΈ΄ΰΈ™ 20 ตัวอักษร"
64 email_guide: "ΰΈΰΈ£ΰΈΈΰΈ“ΰΈ²ΰΈ•ΰΈ£ΰΈ§ΰΈˆΰΈͺอบ e-mail ΰΈ—ΰΈ΅ΰΉˆΰΉƒΰΈͺΰΉˆΰΉƒΰΈ«ΰΉ‰ΰΈ–ΰΈΉΰΈΰΈ•ΰΉ‰ΰΈ­ΰΈ‡<br/>ΰΈ„ΰΈΈΰΈ“ΰΈˆΰΈ°ΰΈ•ΰΉ‰ΰΈ­ΰΈ‡ΰΈ’ΰΈ·ΰΈ™ΰΈ’ΰΈ±ΰΈ™ΰΈΰΈ²ΰΈ£ΰΈ₯ΰΈ‡ΰΈ—ΰΈ°ΰΉ€ΰΈšΰΈ΅ΰΈ’ΰΈ™ΰΈœΰΉˆΰΈ²ΰΈ™ΰΈ—ΰΈ²ΰΈ‡ΰΈ‚ΰΉ‰ΰΈ­ΰΈ‘ΰΈΉΰΈ₯ΰΈ—ΰΈ΅ΰΉˆΰΈˆΰΈ°ΰΈͺΰΉˆΰΈ‡ΰΉƒΰΈ«ΰΉ‰ΰΈ—ΰΈ²ΰΈ‡ e-mail"
64 email_guide: "ΰΈΰΈ£ΰΈΈΰΈ“ΰΈ²ΰΈ•ΰΈ£ΰΈ§ΰΈˆΰΈͺอบ e-mail ΰΈ—ΰΈ΅ΰΉˆΰΉƒΰΈͺΰΉˆΰΉƒΰΈ«ΰΉ‰ΰΈ–ΰΈΉΰΈΰΈ•ΰΉ‰ΰΈ­ΰΈ‡<br/>ΰΈ„ΰΈΈΰΈ“ΰΈˆΰΈ°ΰΈ•ΰΉ‰ΰΈ­ΰΈ‡ΰΈ’ΰΈ·ΰΈ™ΰΈ’ΰΈ±ΰΈ™ΰΈΰΈ²ΰΈ£ΰΈ₯ΰΈ‡ΰΈ—ΰΈ°ΰΉ€ΰΈšΰΈ΅ΰΈ’ΰΈ™ΰΈœΰΉˆΰΈ²ΰΈ™ΰΈ—ΰΈ²ΰΈ‡ΰΈ‚ΰΉ‰ΰΈ­ΰΈ‘ΰΈΉΰΈ₯ΰΈ—ΰΈ΅ΰΉˆΰΈˆΰΈ°ΰΈͺΰΉˆΰΈ‡ΰΉƒΰΈ«ΰΉ‰ΰΈ—ΰΈ²ΰΈ‡ e-mail"
65 register: "ΰΈ₯ΰΈ‡ΰΈ—ΰΈ°ΰΉ€ΰΈšΰΈ΅ΰΈ’ΰΈ™"
65 register: "ΰΈ₯ΰΈ‡ΰΈ—ΰΈ°ΰΉ€ΰΈšΰΈ΅ΰΈ’ΰΈ™"
66
66
67 email_body: "ΰΈͺΰΈ§ΰΈ±ΰΈͺΰΈ”ΰΈ΅ΰΈ„ΰΈ£ΰΈ±ΰΈš {{full_name}},
67 email_body: "ΰΈͺΰΈ§ΰΈ±ΰΈͺΰΈ”ΰΈ΅ΰΈ„ΰΈ£ΰΈ±ΰΈš {{full_name}},
68
68
69 ΰΈ„ΰΈΈΰΈ“ΰΉ„ΰΈ”ΰΉ‰ΰΈ₯ΰΈ‡ΰΈ—ΰΈ°ΰΉ€ΰΈšΰΈ΅ΰΈ’ΰΈ™ΰΉ€ΰΈ‚ΰΉ‰ΰΈ²ΰΈ£ΰΉˆΰΈ§ΰΈ‘ΰΈΰΈ²ΰΈ£ΰΉΰΈ‚ΰΉˆΰΈ‡ΰΈ‚ΰΈ±ΰΈ™ {{contest_name}}
69 ΰΈ„ΰΈΈΰΈ“ΰΉ„ΰΈ”ΰΉ‰ΰΈ₯ΰΈ‡ΰΈ—ΰΈ°ΰΉ€ΰΈšΰΈ΅ΰΈ’ΰΈ™ΰΉ€ΰΈ‚ΰΉ‰ΰΈ²ΰΈ£ΰΉˆΰΈ§ΰΈ‘ΰΈΰΈ²ΰΈ£ΰΉΰΈ‚ΰΉˆΰΈ‡ΰΈ‚ΰΈ±ΰΈ™ {{contest_name}}
70
70
71 ΰΈšΰΈ±ΰΈΰΈŠΰΈ΅ΰΉ€ΰΈ‚ΰΉ‰ΰΈ²ΰΉƒΰΈŠΰΉ‰ΰΈ‚ΰΈ­ΰΈ‡ΰΈ„ΰΈΈΰΈ“ΰΈ„ΰΈ·ΰΈ­: {{login}}
71 ΰΈšΰΈ±ΰΈΰΈŠΰΈ΅ΰΉ€ΰΈ‚ΰΉ‰ΰΈ²ΰΉƒΰΈŠΰΉ‰ΰΈ‚ΰΈ­ΰΈ‡ΰΈ„ΰΈΈΰΈ“ΰΈ„ΰΈ·ΰΈ­: {{login}}
72
72
73 ΰΈ£ΰΈ«ΰΈ±ΰΈͺΰΈœΰΉˆΰΈ²ΰΈ™ΰΈ„ΰΈ·ΰΈ­: {{password}}
73 ΰΈ£ΰΈ«ΰΈ±ΰΈͺΰΈœΰΉˆΰΈ²ΰΈ™ΰΈ„ΰΈ·ΰΈ­: {{password}}
74
74
75 กรุณาเข้าΰΈ₯ΰΈ΄ΰΈ‡ΰΈΰΉŒΰΈ•ΰΉˆΰΈ­ΰΉ„ΰΈ›ΰΈ™ΰΈ΅ΰΉ‰:
75 กรุณาเข้าΰΈ₯ΰΈ΄ΰΈ‡ΰΈΰΉŒΰΈ•ΰΉˆΰΈ­ΰΉ„ΰΈ›ΰΈ™ΰΈ΅ΰΉ‰:
76
76
77 {{activation_url}}
77 {{activation_url}}
78
78
79 ΰΉ€ΰΈžΰΈ·ΰΉˆΰΈ­ΰΉ€ΰΈ›ΰΈ΄ΰΈ”ΰΉƒΰΈŠΰΉ‰ΰΈ‡ΰΈ²ΰΈ™ΰΈšΰΈ±ΰΈΰΈŠΰΈ΅ΰΈ‚ΰΈ­ΰΈ‡ΰΈ„ΰΈΈΰΈ“
79 ΰΉ€ΰΈžΰΈ·ΰΉˆΰΈ­ΰΉ€ΰΈ›ΰΈ΄ΰΈ”ΰΉƒΰΈŠΰΉ‰ΰΈ‡ΰΈ²ΰΈ™ΰΈšΰΈ±ΰΈΰΈŠΰΈ΅ΰΈ‚ΰΈ­ΰΈ‡ΰΈ„ΰΈΈΰΈ“
80
80
81 - ΰΈ–ΰΉ‰ΰΈ²ΰΈ„ΰΈΈΰΈ“ΰΉ„ΰΈ‘ΰΉˆΰΉƒΰΈŠΰΉ‰ΰΈ„ΰΈ™ΰΈ—ΰΈ΅ΰΉˆΰΈ₯ΰΈ‡ΰΈ—ΰΈ°ΰΉ€ΰΈšΰΈ΅ΰΈ’ΰΈ™ กรุณาΰΈ₯ΰΈ°ΰΈ—ΰΈ΄ΰΉ‰ΰΈ‡ e-mail ΰΈ‰ΰΈšΰΈ±ΰΈšΰΈ™ΰΈ΅ΰΉ‰
81 + ΰΈ–ΰΉ‰ΰΈ²ΰΈ„ΰΈΈΰΈ“ΰΉ„ΰΈ‘ΰΉˆΰΉƒΰΈŠΰΉˆΰΈ„ΰΈ™ΰΈ—ΰΈ΅ΰΉˆΰΈ₯ΰΈ‡ΰΈ—ΰΈ°ΰΉ€ΰΈšΰΈ΅ΰΈ’ΰΈ™ กรุณาΰΈ₯ΰΈ°ΰΈ—ΰΈ΄ΰΉ‰ΰΈ‡ e-mail ΰΈ‰ΰΈšΰΈ±ΰΈšΰΈ™ΰΈ΅ΰΉ‰
82 - แΰΈ₯ΰΈ°ΰΉΰΈˆΰΉ‰ΰΈ‡ΰΈ„ΰΈ§ΰΈ²ΰΈ‘ΰΈœΰΈ΄ΰΈ”ΰΈžΰΈ₯ΰΈ²ΰΈ”ΰΈ™ΰΈ΅ΰΉ‰ΰΈΰΈ±ΰΈš {{admin_email}}
82 + แΰΈ₯ΰΈ°ΰΉΰΈˆΰΉ‰ΰΈ‡ΰΈ„ΰΈ§ΰΈ²ΰΈ‘ΰΈœΰΈ΄ΰΈ”ΰΈžΰΈ₯ΰΈ²ΰΈ”ΰΈ™ΰΈ΅ΰΉ‰ΰΈΰΈ±ΰΈš {{admin_email}} ΰΈ”ΰΉ‰ΰΈ§ΰΈ’
83
83
84 ΰΈ‚ΰΈ­ΰΈšΰΈ„ΰΈΈΰΈ“ΰΈ‘ΰΈ²ΰΈ!"
84 ΰΈ‚ΰΈ­ΰΈšΰΈ„ΰΈΈΰΈ“ΰΈ‘ΰΈ²ΰΈ!"
85
85
86 email_sent: "ΰΉ€ΰΈ£ΰΈ²ΰΉ„ΰΈ”ΰΉ‰ΰΈͺΰΉˆΰΈ‡ΰΈ‚ΰΉ‰ΰΈ­ΰΈ‘ΰΈΉΰΈ₯ΰΈͺΰΈ³ΰΈ«ΰΈ£ΰΈ±ΰΈšΰΈ’ΰΈ·ΰΈ™ΰΈ’ΰΈ±ΰΈ™ΰΉ„ΰΈ›ΰΉƒΰΈ«ΰΉ‰ΰΈ„ΰΈΈΰΈ“ΰΉΰΈ₯ΰΉ‰ΰΈ§ (ΰΉ‚ΰΈ›ΰΈ£ΰΈ”ΰΈ­ΰΈ’ΰΉˆΰΈ²ΰΈ₯ΰΈ·ΰΈ‘ΰΈ•ΰΈ£ΰΈ§ΰΈˆΰΈ”ΰΈΉΰΉƒΰΈ™ΰΈͺΰΉˆΰΈ§ΰΈ™ Junk mail ΰΈ”ΰΉ‰ΰΈ§ΰΈ’)"
86 email_sent: "ΰΉ€ΰΈ£ΰΈ²ΰΉ„ΰΈ”ΰΉ‰ΰΈͺΰΉˆΰΈ‡ΰΈ‚ΰΉ‰ΰΈ­ΰΈ‘ΰΈΉΰΈ₯ΰΈͺΰΈ³ΰΈ«ΰΈ£ΰΈ±ΰΈšΰΈ’ΰΈ·ΰΈ™ΰΈ’ΰΈ±ΰΈ™ΰΉ„ΰΈ›ΰΉƒΰΈ«ΰΉ‰ΰΈ„ΰΈΈΰΈ“ΰΉΰΈ₯ΰΉ‰ΰΈ§ (ΰΉ‚ΰΈ›ΰΈ£ΰΈ”ΰΈ­ΰΈ’ΰΉˆΰΈ²ΰΈ₯ΰΈ·ΰΈ‘ΰΈ•ΰΈ£ΰΈ§ΰΈˆΰΈ”ΰΈΉΰΉƒΰΈ™ΰΈͺΰΉˆΰΈ§ΰΈ™ Junk mail ΰΈ”ΰΉ‰ΰΈ§ΰΈ’)"
87 email_verify_at: "ΰΈΰΈ£ΰΈΈΰΈ“ΰΈ²ΰΈ•ΰΈ£ΰΈ§ΰΈˆΰΈͺΰΈ­ΰΈšΰΈ—ΰΈ΅ΰΉˆ {{email}} ΰΈžΰΈ£ΰΉ‰ΰΈ­ΰΈ‘ΰΈ—ΰΈ±ΰΉ‰ΰΈ‡ΰΈ’ΰΈ·ΰΈ™ΰΈ’ΰΈ±ΰΈ™"
87 email_verify_at: "ΰΈΰΈ£ΰΈΈΰΈ“ΰΈ²ΰΈ•ΰΈ£ΰΈ§ΰΈˆΰΈͺΰΈ­ΰΈšΰΈ—ΰΈ΅ΰΉˆ {{email}} ΰΈžΰΈ£ΰΉ‰ΰΈ­ΰΈ‘ΰΈ—ΰΈ±ΰΉ‰ΰΈ‡ΰΈ’ΰΈ·ΰΈ™ΰΈ’ΰΈ±ΰΈ™"
88
88
89 activation_sucessful_title: "ΰΈšΰΈ±ΰΈ“ΰΈŠΰΈ΅ΰΈœΰΈΉΰΉ‰ΰΉƒΰΈŠΰΉ‰ΰΉ„ΰΈ”ΰΉ‰ΰΈ£ΰΈ±ΰΈšΰΈΰΈ²ΰΈ£ΰΈ’ΰΈ·ΰΈ™ΰΈ’ΰΈ±ΰΈ™ΰΉΰΈ₯ΰΉ‰ΰΈ§"
89 activation_sucessful_title: "ΰΈšΰΈ±ΰΈ“ΰΈŠΰΈ΅ΰΈœΰΈΉΰΉ‰ΰΉƒΰΈŠΰΉ‰ΰΉ„ΰΈ”ΰΉ‰ΰΈ£ΰΈ±ΰΈšΰΈΰΈ²ΰΈ£ΰΈ’ΰΈ·ΰΈ™ΰΈ’ΰΈ±ΰΈ™ΰΉΰΈ₯ΰΉ‰ΰΈ§"
90 account_activated: "ΰΈšΰΈ±ΰΈΰΈŠΰΈ΅ΰΈœΰΈΉΰΉ‰ΰΉƒΰΈŠΰΉ‰ΰΈ‚ΰΈ­ΰΈ‡ΰΈ„ΰΈΈΰΈ“ΰΈžΰΈ£ΰΉ‰ΰΈ­ΰΈ‘ΰΉƒΰΈŠΰΉ‰ΰΈ‡ΰΈ²ΰΈ™ΰΉΰΈ₯ΰΉ‰ΰΈ§"
90 account_activated: "ΰΈšΰΈ±ΰΈΰΈŠΰΈ΅ΰΈœΰΈΉΰΉ‰ΰΉƒΰΈŠΰΉ‰ΰΈ‚ΰΈ­ΰΈ‡ΰΈ„ΰΈΈΰΈ“ΰΈžΰΈ£ΰΉ‰ΰΈ­ΰΈ‘ΰΉƒΰΈŠΰΉ‰ΰΈ‡ΰΈ²ΰΈ™ΰΉΰΈ₯ΰΉ‰ΰΈ§"
91
91
92 activation_failed_title: "การฒืนฒันΰΈ₯ΰΉ‰ΰΈ‘ΰΉ€ΰΈ«ΰΈ₯ΰΈ§"
92 activation_failed_title: "การฒืนฒันΰΈ₯ΰΉ‰ΰΈ‘ΰΉ€ΰΈ«ΰΈ₯ΰΈ§"
93
93
94 errors:
94 errors:
95 header: 'การΰΈ₯ΰΈ‡ΰΈ—ΰΈ°ΰΉ€ΰΈšΰΈ΅ΰΈ’ΰΈ™ΰΈ‘ΰΈ΅ΰΈ‚ΰΉ‰ΰΈ­ΰΈœΰΈ΄ΰΈ”ΰΈžΰΈ₯ΰΈ²ΰΈ”'
95 header: 'การΰΈ₯ΰΈ‡ΰΈ—ΰΈ°ΰΉ€ΰΈšΰΈ΅ΰΈ’ΰΈ™ΰΈ‘ΰΈ΅ΰΈ‚ΰΉ‰ΰΈ­ΰΈœΰΈ΄ΰΈ”ΰΈžΰΈ₯ΰΈ²ΰΈ”'
96 email:
96 email:
97 title: "ΰΉ€ΰΈΰΈ΄ΰΈ”ΰΈ›ΰΈ±ΰΈΰΈ«ΰΈ²ΰΈ£ΰΈ°ΰΈ«ΰΈ§ΰΉˆΰΈ²ΰΈ‡ΰΈΰΈ²ΰΈ£ΰΈͺΰΉˆΰΈ‡ e-mail ΰΉ€ΰΈžΰΈ·ΰΉˆΰΈ­ΰΈ’ΰΈ·ΰΈ™ΰΈ’ΰΈ±ΰΈ™ΰΈΰΈ²ΰΈ£ΰΈͺΰΈ‘ΰΈ±ΰΈ„ΰΈ£"
97 title: "ΰΉ€ΰΈΰΈ΄ΰΈ”ΰΈ›ΰΈ±ΰΈΰΈ«ΰΈ²ΰΈ£ΰΈ°ΰΈ«ΰΈ§ΰΉˆΰΈ²ΰΈ‡ΰΈΰΈ²ΰΈ£ΰΈͺΰΉˆΰΈ‡ e-mail ΰΉ€ΰΈžΰΈ·ΰΉˆΰΈ­ΰΈ’ΰΈ·ΰΈ™ΰΈ’ΰΈ±ΰΈ™ΰΈΰΈ²ΰΈ£ΰΈͺΰΈ‘ΰΈ±ΰΈ„ΰΈ£"
98 expl: "<h2>ΰΈšΰΈ±ΰΈΰΈŠΰΈ΅ΰΈœΰΈΉΰΉ‰ΰΉƒΰΈŠΰΉ‰ΰΈ‚ΰΈ­ΰΈ‡ΰΈ„ΰΈΈΰΈ“ΰΈ–ΰΈΉΰΈΰΈͺร้างขย้นแΰΈ₯ΰΉ‰ΰΈ§ ΰΉΰΈ•ΰΉˆΰΈ£ΰΈ°ΰΈšΰΈšΰΉ„ΰΈ‘ΰΉˆΰΈͺΰΈ²ΰΈ‘ΰΈ²ΰΈ£ΰΈ–ΰΈͺΰΉˆΰΈ‡ e-mail ΰΉ€ΰΈžΰΈ·ΰΉˆΰΈ­ΰΈ’ΰΈ·ΰΈ™ΰΈ’ΰΈ±ΰΈ™ΰΈΰΈ²ΰΈ£ΰΈͺΰΈ‘ΰΈ±ΰΈ„ΰΈ£ΰΉ„ΰΈ”ΰΉ‰</h2>
98 expl: "<h2>ΰΈšΰΈ±ΰΈΰΈŠΰΈ΅ΰΈœΰΈΉΰΉ‰ΰΉƒΰΈŠΰΉ‰ΰΈ‚ΰΈ­ΰΈ‡ΰΈ„ΰΈΈΰΈ“ΰΈ–ΰΈΉΰΈΰΈͺร้างขย้นแΰΈ₯ΰΉ‰ΰΈ§ ΰΉΰΈ•ΰΉˆΰΈ£ΰΈ°ΰΈšΰΈšΰΉ„ΰΈ‘ΰΉˆΰΈͺΰΈ²ΰΈ‘ΰΈ²ΰΈ£ΰΈ–ΰΈͺΰΉˆΰΈ‡ e-mail ΰΉ€ΰΈžΰΈ·ΰΉˆΰΈ­ΰΈ’ΰΈ·ΰΈ™ΰΈ’ΰΈ±ΰΈ™ΰΈΰΈ²ΰΈ£ΰΈͺΰΈ‘ΰΈ±ΰΈ„ΰΈ£ΰΉ„ΰΈ”ΰΉ‰</h2>
99 ΰΈ­ΰΈ²ΰΈˆΰΉ€ΰΈΰΈ΄ΰΈ”ΰΈ›ΰΈ±ΰΈΰΈ«ΰΈ²ΰΉƒΰΈ™ΰΈΰΈ²ΰΈ£ΰΈ•ΰΈ±ΰΉ‰ΰΈ‡ΰΈ„ΰΉˆΰΈ²ΰΉ€ΰΈ£ΰΈ΄ΰΉˆΰΈ‘ΰΈ•ΰΉ‰ΰΈ™ΰΈ‚ΰΈ­ΰΈ‡ΰΈ£ΰΈ°ΰΈšΰΈš ΰΈΰΈ£ΰΈΈΰΈ“ΰΈ²ΰΈŠΰΉˆΰΈ§ΰΈ’ΰΈ•ΰΈ΄ΰΈ”ΰΈ•ΰΉˆΰΈ­ΰΈœΰΈΉΰΉ‰ΰΈ”ΰΈΉΰΉΰΈ₯ΰΈ£ΰΈ°ΰΈšΰΈšΰΈ”ΰΉ‰ΰΈ§ΰΈ’ΰΈ—ΰΈ΅ΰΉˆ {{email}}<br/>ΰΈ‚ΰΈ­ΰΈ‚ΰΈ­ΰΈšΰΈ„ΰΈΈΰΈ“ΰΈˆΰΈ²ΰΈΰΈ—ΰΈ΅ΰΈ‘ΰΈ‡ΰΈ²ΰΈ™"
99 ΰΈ­ΰΈ²ΰΈˆΰΉ€ΰΈΰΈ΄ΰΈ”ΰΈ›ΰΈ±ΰΈΰΈ«ΰΈ²ΰΉƒΰΈ™ΰΈΰΈ²ΰΈ£ΰΈ•ΰΈ±ΰΉ‰ΰΈ‡ΰΈ„ΰΉˆΰΈ²ΰΉ€ΰΈ£ΰΈ΄ΰΉˆΰΈ‘ΰΈ•ΰΉ‰ΰΈ™ΰΈ‚ΰΈ­ΰΈ‡ΰΈ£ΰΈ°ΰΈšΰΈš ΰΈΰΈ£ΰΈΈΰΈ“ΰΈ²ΰΈŠΰΉˆΰΈ§ΰΈ’ΰΈ•ΰΈ΄ΰΈ”ΰΈ•ΰΉˆΰΈ­ΰΈœΰΈΉΰΉ‰ΰΈ”ΰΈΉΰΉΰΈ₯ΰΈ£ΰΈ°ΰΈšΰΈšΰΈ”ΰΉ‰ΰΈ§ΰΈ’ΰΈ—ΰΈ΅ΰΉˆ {{email}}<br/>ΰΈ‚ΰΈ­ΰΈ‚ΰΈ­ΰΈšΰΈ„ΰΈΈΰΈ“ΰΈˆΰΈ²ΰΈΰΈ—ΰΈ΅ΰΈ‘ΰΈ‡ΰΈ²ΰΈ™"
100 activation:
100 activation:
101 email_exists: "ΰΈ‘ΰΈ΅ΰΈœΰΈΉΰΉ‰ΰΉƒΰΈŠΰΉ‰ΰΈ—ΰΈ΅ΰΉˆΰΉƒΰΈŠΰΉ‰ e-mail นม้แΰΈ₯ΰΉ‰ΰΈ§"
101 email_exists: "ΰΈ‘ΰΈ΅ΰΈœΰΈΉΰΉ‰ΰΉƒΰΈŠΰΉ‰ΰΈ—ΰΈ΅ΰΉˆΰΉƒΰΈŠΰΉ‰ e-mail นม้แΰΈ₯ΰΉ‰ΰΈ§"
102 invalid: "ΰΈ£ΰΈ«ΰΈ±ΰΈͺΰΈͺΰΈ³ΰΈ«ΰΈ£ΰΈ±ΰΈšΰΈ’ΰΈ·ΰΈ™ΰΈ’ΰΈ±ΰΈ™ΰΈœΰΈ΄ΰΈ”ΰΈžΰΈ₯ΰΈ²ΰΈ” ΰΈΰΈ£ΰΈΈΰΈ“ΰΈ²ΰΈ•ΰΈ£ΰΈ§ΰΈˆΰΈͺΰΈ­ΰΈšΰΈ­ΰΈ΅ΰΈΰΈ„ΰΈ£ΰΈ±ΰΉ‰ΰΈ‡"
102 invalid: "ΰΈ£ΰΈ«ΰΈ±ΰΈͺΰΈͺΰΈ³ΰΈ«ΰΈ£ΰΈ±ΰΈšΰΈ’ΰΈ·ΰΈ™ΰΈ’ΰΈ±ΰΈ™ΰΈœΰΈ΄ΰΈ”ΰΈžΰΈ₯ΰΈ²ΰΈ” ΰΈΰΈ£ΰΈΈΰΈ“ΰΈ²ΰΈ•ΰΈ£ΰΈ§ΰΈˆΰΈͺΰΈ­ΰΈšΰΈ­ΰΈ΅ΰΈΰΈ„ΰΈ£ΰΈ±ΰΉ‰ΰΈ‡"
103
103
104 password_retrieval:
104 password_retrieval:
105 header: "การขอรหัΰΈͺΰΈœΰΉˆΰΈ²ΰΈ™ΰΉƒΰΈ«ΰΈ‘ΰΉˆ"
105 header: "การขอรหัΰΈͺΰΈœΰΉˆΰΈ²ΰΈ™ΰΉƒΰΈ«ΰΈ‘ΰΉˆ"
106 instructions: "กรุณากรอก e-mail ΰΈ—ΰΈ΅ΰΉˆΰΈ₯ΰΈ‡ΰΈ—ΰΈ°ΰΉ€ΰΈšΰΈ΅ΰΈ’ΰΈ™"
106 instructions: "กรุณากรอก e-mail ΰΈ—ΰΈ΅ΰΉˆΰΈ₯ΰΈ‡ΰΈ—ΰΈ°ΰΉ€ΰΈšΰΈ΅ΰΈ’ΰΈ™"
107 button_label: "ΰΈ‚ΰΈ­ΰΈ£ΰΈ«ΰΈ±ΰΈͺΰΈœΰΉˆΰΈ²ΰΈ™ΰΉƒΰΈ«ΰΈ‘ΰΉˆ"
107 button_label: "ΰΈ‚ΰΈ­ΰΈ£ΰΈ«ΰΈ±ΰΈͺΰΈœΰΉˆΰΈ²ΰΈ™ΰΉƒΰΈ«ΰΈ‘ΰΉˆ"
108 no_email: "ΰΉ„ΰΈ‘ΰΉˆΰΈ‘ΰΈ΅ΰΈšΰΈ±ΰΈΰΈŠΰΈ΅ΰΈœΰΈΉΰΉ‰ΰΉƒΰΈŠΰΉ‰ΰΈ—ΰΈ΅ΰΉˆΰΉƒΰΈŠΰΉ‰ e-mail ดังกΰΈ₯่าว"
108 no_email: "ΰΉ„ΰΈ‘ΰΉˆΰΈ‘ΰΈ΅ΰΈšΰΈ±ΰΈΰΈŠΰΈ΅ΰΈœΰΈΉΰΉ‰ΰΉƒΰΈŠΰΉ‰ΰΈ—ΰΈ΅ΰΉˆΰΉƒΰΈŠΰΉ‰ e-mail ดังกΰΈ₯่าว"
109 email_body: "ΰΈͺΰΈ§ΰΈ±ΰΈͺΰΈ”ΰΈ΅ΰΈ„ΰΈ£ΰΈ±ΰΈš {{full_name}},
109 email_body: "ΰΈͺΰΈ§ΰΈ±ΰΈͺΰΈ”ΰΈ΅ΰΈ„ΰΈ£ΰΈ±ΰΈš {{full_name}},
110
110
111 ΰΈ„ΰΈΈΰΈ“ΰΉ„ΰΈ”ΰΉ‰ΰΈ£ΰΉ‰ΰΈ­ΰΈ‡ΰΈ‚ΰΈ­ΰΈ£ΰΈ«ΰΈ±ΰΈͺΰΈœΰΉˆΰΈ²ΰΈ™ΰΉƒΰΈ«ΰΈ‘ΰΉˆ ΰΈͺΰΈ³ΰΈ«ΰΈ£ΰΈ±ΰΈšΰΈΰΈ²ΰΈ£ΰΉΰΈ‚ΰΉˆΰΈ‡ΰΈ‚ΰΈ±ΰΈ™ {{contest_name}} ΰΈ‹ΰΈΆΰΉˆΰΈ‡ΰΉ€ΰΈ£ΰΈ²ΰΉ„ΰΈ”ΰΉ‰ΰΈͺร้างให้คุณแΰΈ₯ΰΉ‰ΰΈ§ ΰΈ”ΰΈ±ΰΈ‡ΰΈ™ΰΈ΅ΰΉ‰
111 ΰΈ„ΰΈΈΰΈ“ΰΉ„ΰΈ”ΰΉ‰ΰΈ£ΰΉ‰ΰΈ­ΰΈ‡ΰΈ‚ΰΈ­ΰΈ£ΰΈ«ΰΈ±ΰΈͺΰΈœΰΉˆΰΈ²ΰΈ™ΰΉƒΰΈ«ΰΈ‘ΰΉˆ ΰΈͺΰΈ³ΰΈ«ΰΈ£ΰΈ±ΰΈšΰΈΰΈ²ΰΈ£ΰΉΰΈ‚ΰΉˆΰΈ‡ΰΈ‚ΰΈ±ΰΈ™ {{contest_name}} ΰΈ‹ΰΈΆΰΉˆΰΈ‡ΰΉ€ΰΈ£ΰΈ²ΰΉ„ΰΈ”ΰΉ‰ΰΈͺร้างให้คุณแΰΈ₯ΰΉ‰ΰΈ§ ΰΈ”ΰΈ±ΰΈ‡ΰΈ™ΰΈ΅ΰΉ‰
112
112
113 ΰΈšΰΈ±ΰΈΰΈŠΰΈ΅ΰΉ€ΰΈ‚ΰΉ‰ΰΈ²ΰΉƒΰΈŠΰΉ‰ΰΈ‚ΰΈ­ΰΈ‡ΰΈ„ΰΈΈΰΈ“ΰΈ„ΰΈ·ΰΈ­: {{login}}
113 ΰΈšΰΈ±ΰΈΰΈŠΰΈ΅ΰΉ€ΰΈ‚ΰΉ‰ΰΈ²ΰΉƒΰΈŠΰΉ‰ΰΈ‚ΰΈ­ΰΈ‡ΰΈ„ΰΈΈΰΈ“ΰΈ„ΰΈ·ΰΈ­: {{login}}
114 ΰΈ£ΰΈ«ΰΈ±ΰΈͺΰΈœΰΉˆΰΈ²ΰΈ™ΰΈ„ΰΈ·ΰΈ­: {{password}}
114 ΰΈ£ΰΈ«ΰΈ±ΰΈͺΰΈœΰΉˆΰΈ²ΰΈ™ΰΈ„ΰΈ·ΰΈ­: {{password}}
115
115
116 ΰΈ–ΰΉ‰ΰΈ²ΰΈ„ΰΈΈΰΈ“ΰΉ„ΰΈ‘ΰΉˆΰΉ„ΰΈ”ΰΉ‰ΰΈ‚ΰΈ­ΰΈ£ΰΈ«ΰΈ±ΰΈͺΰΈœΰΉˆΰΈ²ΰΈ™ΰΉƒΰΈ«ΰΈ‘ΰΉˆ ΰΈ«ΰΈ£ΰΈ·ΰΈ­ΰΉ„ΰΈ‘ΰΉˆΰΉƒΰΈŠΰΉˆΰΈ„ΰΈ™ΰΈ—ΰΈ΅ΰΉˆΰΈ₯ΰΈ‡ΰΈ—ΰΈ°ΰΉ€ΰΈšΰΈ΅ΰΈ’ΰΈ™ กรุณาΰΈ₯ΰΈ°ΰΈ—ΰΈ΄ΰΉ‰ΰΈ‡ e-mail ΰΈ‰ΰΈšΰΈ±ΰΈšΰΈ™ΰΈ΅ΰΉ‰
116 ΰΈ–ΰΉ‰ΰΈ²ΰΈ„ΰΈΈΰΈ“ΰΉ„ΰΈ‘ΰΉˆΰΉ„ΰΈ”ΰΉ‰ΰΈ‚ΰΈ­ΰΈ£ΰΈ«ΰΈ±ΰΈͺΰΈœΰΉˆΰΈ²ΰΈ™ΰΉƒΰΈ«ΰΈ‘ΰΉˆ ΰΈ«ΰΈ£ΰΈ·ΰΈ­ΰΉ„ΰΈ‘ΰΉˆΰΉƒΰΈŠΰΉˆΰΈ„ΰΈ™ΰΈ—ΰΈ΅ΰΉˆΰΈ₯ΰΈ‡ΰΈ—ΰΈ°ΰΉ€ΰΈšΰΈ΅ΰΈ’ΰΈ™ กรุณาΰΈ₯ΰΈ°ΰΈ—ΰΈ΄ΰΉ‰ΰΈ‡ e-mail ΰΈ‰ΰΈšΰΈ±ΰΈšΰΈ™ΰΈ΅ΰΉ‰
117 - แΰΈ₯ΰΈ°ΰΉΰΈˆΰΉ‰ΰΈ‡ΰΈ„ΰΈ§ΰΈ²ΰΈ‘ΰΈœΰΈ΄ΰΈ”ΰΈžΰΈ₯ΰΈ²ΰΈ”ΰΈ™ΰΈ΅ΰΉ‰ΰΈΰΈ±ΰΈš {{admin_email}}
117 + แΰΈ₯ΰΈ°ΰΉΰΈˆΰΉ‰ΰΈ‡ΰΈ„ΰΈ§ΰΈ²ΰΈ‘ΰΈœΰΈ΄ΰΈ”ΰΈžΰΈ₯ΰΈ²ΰΈ”ΰΈ™ΰΈ΅ΰΉ‰ΰΈΰΈ±ΰΈš {{admin_email}} ΰΈ”ΰΉ‰ΰΈ§ΰΈ’
118
118
119 ΰΈ‚ΰΈ­ΰΈšΰΈ„ΰΈΈΰΈ“ΰΈ‘ΰΈ²ΰΈ!"
119 ΰΈ‚ΰΈ­ΰΈšΰΈ„ΰΈΈΰΈ“ΰΈ‘ΰΈ²ΰΈ!"
120
120
121 + contest:
122 + notification:
123 + email_subject: "[{{contest_title_name}}] ΰΈ„ΰΈΈΰΈ“ΰΉ„ΰΈ”ΰΉ‰ΰΈ£ΰΈ±ΰΈšΰΈΰΈ²ΰΈ£ΰΉ€ΰΈ₯ΰΈ·ΰΉˆΰΈ­ΰΈ™ΰΈ‚ΰΈ±ΰΉ‰ΰΈ™ΰΈͺΰΈΉΰΉˆΰΈ£ΰΈ°ΰΈ”ΰΈ±ΰΈš {{contest_name}}"
124 + email_body: "ขอแΰΈͺΰΈ”ΰΈ‡ΰΈ„ΰΈ§ΰΈ²ΰΈ‘ΰΈ’ΰΈ΄ΰΈ™ΰΈ”ΰΈ΅ΰΈ”ΰΉ‰ΰΈ§ΰΈ’ ΰΈ„ΰΈΈΰΈ“{{full_name}}
125 +
126 + ΰΈ„ΰΈΈΰΈ“ΰΉ„ΰΈ”ΰΉ‰ΰΈ£ΰΈ±ΰΈšΰΈΰΈ²ΰΈ£ΰΉ€ΰΈ₯ΰΈ·ΰΉˆΰΈ­ΰΈ™ΰΈ‚ΰΈ±ΰΉ‰ΰΈ™ΰΉƒΰΈ«ΰΉ‰ΰΈͺΰΈ²ΰΈ‘ΰΈ²ΰΈ£ΰΈ–ΰΉΰΈ‚ΰΉˆΰΈ‡ΰΈ‚ΰΈ±ΰΈ™ΰΉƒΰΈ™ΰΈΰΈ²ΰΈ£ΰΉΰΈ‚ΰΉˆΰΈ‡ΰΈ‚ΰΈ±ΰΈ™ΰΈ£ΰΈ°ΰΈ”ΰΈ±ΰΈš {{contest_name}} ΰΈ‚ΰΈ­ΰΈ‡ {{contest_title_name}} แΰΈ₯ΰΉ‰ΰΈ§
127 +
128 + ΰΈ„ΰΈΈΰΈ“ΰΈͺΰΈ²ΰΈ‘ΰΈ²ΰΈ£ΰΈ–ΰΉ€ΰΈ‚ΰΉ‰ΰΈ²ΰΈͺΰΈΉΰΉˆΰΈ£ΰΈ°ΰΈšΰΈšΰΉ€ΰΈžΰΈ·ΰΉˆΰΈ­ΰΈ—ΰΈ³ΰΉ‚ΰΈˆΰΈ—ΰΈ’ΰΉŒΰΉ„ΰΈ”ΰΉ‰ΰΈ—ΰΈ±ΰΈ™ΰΈ—ΰΈ΅ ΰΈ„ΰΈΈΰΈ“ΰΈͺΰΈ²ΰΈ‘ΰΈ²ΰΈ£ΰΈ–ΰΉΰΈ‚ΰΉˆΰΈ‡ΰΉƒΰΈ™ΰΈ£ΰΈ°ΰΈ”ΰΈ±ΰΈš {{contest_name}} ΰΉ„ΰΈ”ΰΉ‰ΰΈˆΰΈ™ΰΈΰΈ£ΰΈ°ΰΈ—ΰΈ±ΰΉˆΰΈ‡ΰΈΰΈ²ΰΈ£ΰΉΰΈ‚ΰΉˆΰΈ‡ΰΈ‚ΰΈ±ΰΈ™ΰΈ£ΰΈ­ΰΈšΰΈ™ΰΈ΅ΰΉ‰ΰΈͺΰΈ΄ΰΉ‰ΰΈ™ΰΈͺΰΈΈΰΈ”ΰΈ₯ΰΈ‡
129 +
130 + -ΰΈ—ΰΈ΅ΰΈ‘ΰΈ‡ΰΈ²ΰΈ™ {{contest_title_name}}"
131 +
132 +
121 help:
133 help:
122 how_to_submit: "วิธมการΰΈͺΰΉˆΰΈ‡ΰΉ‚ΰΈ›ΰΈ£ΰΉΰΈΰΈ£ΰΈ‘"
134 how_to_submit: "วิธมการΰΈͺΰΉˆΰΈ‡ΰΉ‚ΰΈ›ΰΈ£ΰΉΰΈΰΈ£ΰΈ‘"
123 must_specify_language: "ΰΈ„ΰΈΈΰΈ“<b>ΰΈ•ΰΉ‰ΰΈ­ΰΈ‡</b>ΰΈ£ΰΈ°ΰΈšΰΈΈΰΈ ΰΈ²ΰΈ©ΰΈ²ΰΉ‚ΰΈ›ΰΈ£ΰΉΰΈΰΈ£ΰΈ‘ΰΈ—ΰΈ΅ΰΉˆΰΉƒΰΈŠΰΉ‰ΰΈ—ΰΈ΅ΰΉˆΰΈ•ΰΈ­ΰΈ™ΰΈ•ΰΉ‰ΰΈ™ΰΈ‚ΰΈ­ΰΈ‡ΰΈ£ΰΈ«ΰΈ±ΰΈͺโปรแกรฑ (source code) ΰΈ™ΰΈ­ΰΈΰΈˆΰΈ²ΰΈΰΈ™ΰΈ΅ΰΉ‰ΰΈ„ΰΈΈΰΈ“ΰΈ­ΰΈ²ΰΈˆΰΈˆΰΈ°ΰΈ£ΰΈ°ΰΈšΰΈΈΰΉ‚ΰΈˆΰΈ—ΰΈ’ΰΉŒΰΈ—ΰΈ΅ΰΉˆΰΈ•ΰΉ‰ΰΈ­ΰΈ‡ΰΈΰΈ²ΰΈ£ΰΈͺΰΉˆΰΈ‡ΰΉ„ΰΈ”ΰΉ‰ΰΈ”ΰΉ‰ΰΈ§ΰΈ’"
135 must_specify_language: "ΰΈ„ΰΈΈΰΈ“<b>ΰΈ•ΰΉ‰ΰΈ­ΰΈ‡</b>ΰΈ£ΰΈ°ΰΈšΰΈΈΰΈ ΰΈ²ΰΈ©ΰΈ²ΰΉ‚ΰΈ›ΰΈ£ΰΉΰΈΰΈ£ΰΈ‘ΰΈ—ΰΈ΅ΰΉˆΰΉƒΰΈŠΰΉ‰ΰΈ—ΰΈ΅ΰΉˆΰΈ•ΰΈ­ΰΈ™ΰΈ•ΰΉ‰ΰΈ™ΰΈ‚ΰΈ­ΰΈ‡ΰΈ£ΰΈ«ΰΈ±ΰΈͺโปรแกรฑ (source code) ΰΈ™ΰΈ­ΰΈΰΈˆΰΈ²ΰΈΰΈ™ΰΈ΅ΰΉ‰ΰΈ„ΰΈΈΰΈ“ΰΈ­ΰΈ²ΰΈˆΰΈˆΰΈ°ΰΈ£ΰΈ°ΰΈšΰΈΈΰΉ‚ΰΈˆΰΈ—ΰΈ’ΰΉŒΰΈ—ΰΈ΅ΰΉˆΰΈ•ΰΉ‰ΰΈ­ΰΈ‡ΰΈΰΈ²ΰΈ£ΰΈͺΰΉˆΰΈ‡ΰΉ„ΰΈ”ΰΉ‰ΰΈ”ΰΉ‰ΰΈ§ΰΈ’"
124 list_available_language: "ΰΈ ΰΈ²ΰΈ©ΰΈ²ΰΉ‚ΰΈ›ΰΈ£ΰΉΰΈΰΈ£ΰΈ‘ΰΈ—ΰΈ΅ΰΉˆΰΈͺΰΈ²ΰΈ‘ΰΈ²ΰΈ£ΰΈ–ΰΈ£ΰΈ°ΰΈšΰΈΈΰΉ„ΰΈ”ΰΉ‰ΰΈ„ΰΈ·ΰΈ­ <tt>C</tt>, <tt>C++</tt>, แΰΈ₯ΰΈ° <tt>Pascal</tt> ΰΈ”ΰΉ‰ΰΈ²ΰΈ™ΰΈ₯ΰΉˆΰΈ²ΰΈ‡ΰΉΰΈͺΰΈ”ΰΈ‡ΰΈ•ΰΈ±ΰΈ§ΰΈ­ΰΈ’ΰΉˆΰΈ²ΰΈ‡ΰΈ‚ΰΈ­ΰΈ‡ΰΈΰΈ²ΰΈ£ΰΈ£ΰΈ°ΰΈšΰΈΈΰΈͺΰΈ³ΰΈ«ΰΈ£ΰΈ±ΰΈšΰΈ ΰΈ²ΰΈ©ΰΈ²ΰΈ•ΰΉˆΰΈ²ΰΈ‡ ΰΉ†"
136 list_available_language: "ΰΈ ΰΈ²ΰΈ©ΰΈ²ΰΉ‚ΰΈ›ΰΈ£ΰΉΰΈΰΈ£ΰΈ‘ΰΈ—ΰΈ΅ΰΉˆΰΈͺΰΈ²ΰΈ‘ΰΈ²ΰΈ£ΰΈ–ΰΈ£ΰΈ°ΰΈšΰΈΈΰΉ„ΰΈ”ΰΉ‰ΰΈ„ΰΈ·ΰΈ­ <tt>C</tt>, <tt>C++</tt>, แΰΈ₯ΰΈ° <tt>Pascal</tt> ΰΈ”ΰΉ‰ΰΈ²ΰΈ™ΰΈ₯ΰΉˆΰΈ²ΰΈ‡ΰΉΰΈͺΰΈ”ΰΈ‡ΰΈ•ΰΈ±ΰΈ§ΰΈ­ΰΈ’ΰΉˆΰΈ²ΰΈ‡ΰΈ‚ΰΈ­ΰΈ‡ΰΈΰΈ²ΰΈ£ΰΈ£ΰΈ°ΰΈšΰΈΈΰΈͺΰΈ³ΰΈ«ΰΈ£ΰΈ±ΰΈšΰΈ ΰΈ²ΰΈ©ΰΈ²ΰΈ•ΰΉˆΰΈ²ΰΈ‡ ΰΉ†"
125 accept_only_language_specified: "ระบบจะ<b>ΰΉ„ΰΈ‘ΰΉˆΰΈ£ΰΈ±ΰΈš</b>ΰΉ‚ΰΈ›ΰΈ£ΰΉΰΈΰΈ£ΰΈ‘ΰΈ—ΰΈ΅ΰΉˆΰΈͺΰΉˆΰΈ‡ΰΈ–ΰΉ‰ΰΈ²ΰΈ„ΰΈΈΰΈ“ΰΉ„ΰΈ‘ΰΉˆΰΉ„ΰΈ”ΰΉ‰ΰΈ£ΰΈ°ΰΈšΰΈΈΰΈ ΰΈ²ΰΈ©ΰΈ²ΰΈ—ΰΈ΅ΰΉˆΰΉƒΰΈŠΰΉ‰"
137 accept_only_language_specified: "ระบบจะ<b>ΰΉ„ΰΈ‘ΰΉˆΰΈ£ΰΈ±ΰΈš</b>ΰΉ‚ΰΈ›ΰΈ£ΰΉΰΈΰΈ£ΰΈ‘ΰΈ—ΰΈ΅ΰΉˆΰΈͺΰΉˆΰΈ‡ΰΈ–ΰΉ‰ΰΈ²ΰΈ„ΰΈΈΰΈ“ΰΉ„ΰΈ‘ΰΉˆΰΉ„ΰΈ”ΰΉ‰ΰΈ£ΰΈ°ΰΈšΰΈΈΰΈ ΰΈ²ΰΈ©ΰΈ²ΰΈ—ΰΈ΅ΰΉˆΰΉƒΰΈŠΰΉ‰"
126 specifying_task: "ΰΈ™ΰΈ­ΰΈΰΈˆΰΈ²ΰΈΰΈ™ΰΈ΅ΰΉ‰ ΰΈ„ΰΈΈΰΈ“ΰΈ’ΰΈ±ΰΈ‡ΰΈͺΰΈ²ΰΈ‘ΰΈ²ΰΈ£ΰΈ–ΰΈ£ΰΈ°ΰΈšΰΈΈΰΈŠΰΈ·ΰΉˆΰΈ­ΰΈ‚ΰΈ­ΰΈ‡ΰΉ‚ΰΈˆΰΈ—ΰΈ’ΰΉŒΰΈ—ΰΈ΅ΰΉˆΰΈ•ΰΉ‰ΰΈ­ΰΈ‡ΰΈΰΈ²ΰΈ£ΰΈͺΰΉˆΰΈ‡ΰΉ€ΰΈžΰΈ΄ΰΉˆΰΈ‘ΰΉ€ΰΈ•ΰΈ΄ΰΈ‘ΰΉ„ΰΈ”ΰΉ‰ ΰΉƒΰΈ™ΰΈΰΈ²ΰΈ£ΰΈ£ΰΈ°ΰΈšΰΈΈΰΉƒΰΈ«ΰΉ‰ΰΉƒΰΈͺ่ <tt>TASK:</tt> <i>taskname</i> ΰΈ„ΰΈΈΰΈ“ΰΈͺΰΈ²ΰΈ‘ΰΈ²ΰΈ£ΰΈ–ΰΈ•ΰΈ£ΰΈ§ΰΈˆΰΈͺΰΈ­ΰΈšΰΈŠΰΈ·ΰΉˆΰΈ­ΰΈ‚ΰΈ­ΰΈ‡ΰΉ‚ΰΈˆΰΈ—ΰΈ’ΰΉŒΰΉ„ΰΈ”ΰΉ‰ ΰΉ‚ΰΈ”ΰΈ’ΰΈˆΰΈ°ΰΉΰΈͺΰΈ”ΰΈ‡ΰΉƒΰΈ™ΰΈ§ΰΈ‡ΰΉ€ΰΈ₯ΰΉ‡ΰΈšΰΈ«ΰΈ₯ΰΈ±ΰΈ‡ΰΈŠΰΈ·ΰΉˆΰΈ­ΰΈ ΰΈ²ΰΈ©ΰΈ²ΰΉ„ΰΈ—ΰΈ’ΰΈ‚ΰΈ­ΰΈ‡ΰΉ‚ΰΈˆΰΈ—ΰΈ’ΰΉŒ"
138 specifying_task: "ΰΈ™ΰΈ­ΰΈΰΈˆΰΈ²ΰΈΰΈ™ΰΈ΅ΰΉ‰ ΰΈ„ΰΈΈΰΈ“ΰΈ’ΰΈ±ΰΈ‡ΰΈͺΰΈ²ΰΈ‘ΰΈ²ΰΈ£ΰΈ–ΰΈ£ΰΈ°ΰΈšΰΈΈΰΈŠΰΈ·ΰΉˆΰΈ­ΰΈ‚ΰΈ­ΰΈ‡ΰΉ‚ΰΈˆΰΈ—ΰΈ’ΰΉŒΰΈ—ΰΈ΅ΰΉˆΰΈ•ΰΉ‰ΰΈ­ΰΈ‡ΰΈΰΈ²ΰΈ£ΰΈͺΰΉˆΰΈ‡ΰΉ€ΰΈžΰΈ΄ΰΉˆΰΈ‘ΰΉ€ΰΈ•ΰΈ΄ΰΈ‘ΰΉ„ΰΈ”ΰΉ‰ ΰΉƒΰΈ™ΰΈΰΈ²ΰΈ£ΰΈ£ΰΈ°ΰΈšΰΈΈΰΉƒΰΈ«ΰΉ‰ΰΉƒΰΈͺ่ <tt>TASK:</tt> <i>taskname</i> ΰΈ„ΰΈΈΰΈ“ΰΈͺΰΈ²ΰΈ‘ΰΈ²ΰΈ£ΰΈ–ΰΈ•ΰΈ£ΰΈ§ΰΈˆΰΈͺΰΈ­ΰΈšΰΈŠΰΈ·ΰΉˆΰΈ­ΰΈ‚ΰΈ­ΰΈ‡ΰΉ‚ΰΈˆΰΈ—ΰΈ’ΰΉŒΰΉ„ΰΈ”ΰΉ‰ ΰΉ‚ΰΈ”ΰΈ’ΰΈˆΰΈ°ΰΉΰΈͺΰΈ”ΰΈ‡ΰΉƒΰΈ™ΰΈ§ΰΈ‡ΰΉ€ΰΈ₯ΰΉ‡ΰΈšΰΈ«ΰΈ₯ΰΈ±ΰΈ‡ΰΈŠΰΈ·ΰΉˆΰΈ­ΰΈ ΰΈ²ΰΈ©ΰΈ²ΰΉ„ΰΈ—ΰΈ’ΰΈ‚ΰΈ­ΰΈ‡ΰΉ‚ΰΈˆΰΈ—ΰΈ’ΰΉŒ"
127 example_cpp: "ΰΈ’ΰΈΰΈ•ΰΈ±ΰΈ§ΰΈ­ΰΈ’ΰΉˆΰΈ²ΰΈ‡ΰΉ€ΰΈŠΰΉˆΰΈ™ ΰΈ–ΰΉ‰ΰΈ²ΰΈ„ΰΈΈΰΈ“ΰΉƒΰΈŠΰΉ‰ΰΈ ΰΈ²ΰΈ©ΰΈ² <tt>C++</tt> ΰΈͺΰΈ³ΰΈ«ΰΈ£ΰΈ±ΰΈšΰΉ€ΰΈ‚ΰΈ΅ΰΈ’ΰΈ™ΰΉ‚ΰΈˆΰΈ—ΰΈ’ΰΉŒ <tt>mobiles</tt> ΰΈ•ΰΈ­ΰΈ™ΰΈ•ΰΉ‰ΰΈ™ΰΉ‚ΰΈ›ΰΈ£ΰΉΰΈΰΈ£ΰΈ‘ΰΈ„ΰΈΈΰΈ“ΰΈˆΰΈ°ΰΉƒΰΈͺΰΉˆΰΈ”ΰΈ±ΰΈ‡ΰΈ™ΰΈ΅ΰΉ‰"
139 example_cpp: "ΰΈ’ΰΈΰΈ•ΰΈ±ΰΈ§ΰΈ­ΰΈ’ΰΉˆΰΈ²ΰΈ‡ΰΉ€ΰΈŠΰΉˆΰΈ™ ΰΈ–ΰΉ‰ΰΈ²ΰΈ„ΰΈΈΰΈ“ΰΉƒΰΈŠΰΉ‰ΰΈ ΰΈ²ΰΈ©ΰΈ² <tt>C++</tt> ΰΈͺΰΈ³ΰΈ«ΰΈ£ΰΈ±ΰΈšΰΉ€ΰΈ‚ΰΈ΅ΰΈ’ΰΈ™ΰΉ‚ΰΈˆΰΈ—ΰΈ’ΰΉŒ <tt>mobiles</tt> ΰΈ•ΰΈ­ΰΈ™ΰΈ•ΰΉ‰ΰΈ™ΰΉ‚ΰΈ›ΰΈ£ΰΉΰΈΰΈ£ΰΈ‘ΰΈ„ΰΈΈΰΈ“ΰΈˆΰΈ°ΰΉƒΰΈͺΰΉˆΰΈ”ΰΈ±ΰΈ‡ΰΈ™ΰΈ΅ΰΉ‰"
128 example_pas: "ΰΈ–ΰΉ‰ΰΈ²ΰΈ„ΰΈΈΰΈ“ΰΉƒΰΈŠΰΉ‰ΰΈ ΰΈ²ΰΈ©ΰΈ² <tt>Pascal</tt> ΰΉ€ΰΈžΰΈ·ΰΉˆΰΈ­ΰΉ€ΰΈ‚ΰΈ΅ΰΈ’ΰΈ™ΰΉ‚ΰΈˆΰΈ—ΰΈ’ΰΉŒΰΈ‚ΰΉ‰ΰΈ­ΰΉ€ΰΈ”ΰΈ΅ΰΈ’ΰΈ§ΰΈΰΈ±ΰΈ™ ΰΈ„ΰΈΈΰΈ“ΰΈˆΰΈ°ΰΈ£ΰΈ°ΰΈšΰΈΈ"
140 example_pas: "ΰΈ–ΰΉ‰ΰΈ²ΰΈ„ΰΈΈΰΈ“ΰΉƒΰΈŠΰΉ‰ΰΈ ΰΈ²ΰΈ©ΰΈ² <tt>Pascal</tt> ΰΉ€ΰΈžΰΈ·ΰΉˆΰΈ­ΰΉ€ΰΈ‚ΰΈ΅ΰΈ’ΰΈ™ΰΉ‚ΰΈˆΰΈ—ΰΈ’ΰΉŒΰΈ‚ΰΉ‰ΰΈ­ΰΉ€ΰΈ”ΰΈ΅ΰΈ’ΰΈ§ΰΈΰΈ±ΰΈ™ ΰΈ„ΰΈΈΰΈ“ΰΈˆΰΈ°ΰΈ£ΰΈ°ΰΈšΰΈΈ"
129 ask_questions_at_messages: "ΰΈ–ΰΉ‰ΰΈ²ΰΈ‘ΰΈ΅ΰΈ›ΰΈ±ΰΈΰΈ«ΰΈ²ΰΉƒΰΈ™ΰΈΰΈ²ΰΈ£ΰΉƒΰΈŠΰΉ‰ΰΈ‡ΰΈ²ΰΈ™ΰΈͺΰΈ²ΰΈ‘ΰΈ²ΰΈ£ΰΈ–ΰΈͺΰΈ­ΰΈšΰΈ–ΰΈ²ΰΈ‘ΰΉ„ΰΈ”ΰΉ‰ΰΈ—ΰΈ΅ΰΉˆΰΈ«ΰΈ™ΰΉ‰ΰΈ²<a href=\"{{url}}\">{{message_link_name}}</a>"
141 ask_questions_at_messages: "ΰΈ–ΰΉ‰ΰΈ²ΰΈ‘ΰΈ΅ΰΈ›ΰΈ±ΰΈΰΈ«ΰΈ²ΰΉƒΰΈ™ΰΈΰΈ²ΰΈ£ΰΉƒΰΈŠΰΉ‰ΰΈ‡ΰΈ²ΰΈ™ΰΈͺΰΈ²ΰΈ‘ΰΈ²ΰΈ£ΰΈ–ΰΈͺΰΈ­ΰΈšΰΈ–ΰΈ²ΰΈ‘ΰΉ„ΰΈ”ΰΉ‰ΰΈ—ΰΈ΅ΰΉˆΰΈ«ΰΈ™ΰΉ‰ΰΈ²<a href=\"{{url}}\">{{message_link_name}}</a>"
130
142
131 activerecord:
143 activerecord:
132 attributes:
144 attributes:
133 user:
145 user:
134 login: "ΰΈŠΰΈ·ΰΉˆΰΈ­ΰΉ€ΰΈ‚ΰΉ‰ΰΈ²ΰΉƒΰΈŠΰΉ‰ΰΈ£ΰΈ°ΰΈšΰΈš"
146 login: "ΰΈŠΰΈ·ΰΉˆΰΈ­ΰΉ€ΰΈ‚ΰΉ‰ΰΈ²ΰΉƒΰΈŠΰΉ‰ΰΈ£ΰΈ°ΰΈšΰΈš"
135 full_name: "ΰΈŠΰΈ·ΰΉˆΰΈ­ΰΉ€ΰΈ•ΰΉ‡ΰΈ‘"
147 full_name: "ΰΈŠΰΈ·ΰΉˆΰΈ­ΰΉ€ΰΈ•ΰΉ‡ΰΈ‘"
136 email: "e-mail"
148 email: "e-mail"
137 province: "ΰΈˆΰΈ±ΰΈ‡ΰΈ«ΰΈ§ΰΈ±ΰΈ”"
149 province: "ΰΈˆΰΈ±ΰΈ‡ΰΈ«ΰΈ§ΰΈ±ΰΈ”"
138
150
@@ -1,90 +1,109
1 require 'spec_helper'
1 require 'spec_helper'
2 require 'config_spec_helper'
2 require 'config_spec_helper'
3 require 'delorean'
3 require 'delorean'
4
4
5 describe "ContestManagements" do
5 describe "ContestManagements" do
6 include ConfigSpecHelperMethods
6 include ConfigSpecHelperMethods
7
7
8 fixtures :users
8 fixtures :users
9 fixtures :problems
9 fixtures :problems
10 fixtures :contests
10 fixtures :contests
11 fixtures :roles
11 fixtures :roles
12
12
13 before(:each) do
13 before(:each) do
14 @admin_user = users(:mary)
14 @admin_user = users(:mary)
15 @contest_b = contests(:contest_b)
15 @contest_b = contests(:contest_b)
16 @james = users(:james)
16 @james = users(:james)
17 @jack = users(:jack)
17 @jack = users(:jack)
18
18
19 set_contest_time_limit('3:00')
19 set_contest_time_limit('3:00')
20 set_indv_contest_mode
20 set_indv_contest_mode
21 enable_multicontest
21 enable_multicontest
22 end
22 end
23
23
24 it "should reset users' timer when their contests change" do
24 it "should reset users' timer when their contests change" do
25 - james_session = open_session
25 + session = open_session
26 - james_session.extend(MainSessionMethods)
26 + session.extend(MainSessionMethods)
27
27
28 - james_login_and_get_main_list(james_session)
28 + james_login_and_get_main_list(session)
29 - james_session.response.should_not have_text(/OVER/)
29 + session.response.should_not have_text(/OVER/)
30
30
31 Delorean.time_travel_to(190.minutes.since) do
31 Delorean.time_travel_to(190.minutes.since) do
32 - james_session.get_main_list
32 + session.get_main_list
33 - james_session.response.should have_text(/OVER/)
33 + session.response.should have_text(/OVER/)
34
34
35 - james_session.get '/' # logout
35 + session.get '/' # logout
36 - james_session.get '/main/list' # clearly log out
36 + session.get '/main/list' # clearly log out
37 - james_session.response.should_not render_template 'main/list'
37 + session.response.should_not render_template 'main/list'
38
38
39 admin_change_users_contest_to("james", @contest_b, true)
39 admin_change_users_contest_to("james", @contest_b, true)
40
40
41 - james_login_and_get_main_list(james_session)
41 + james_login_and_get_main_list(session)
42 - james_session.response.should_not have_text(/OVER/)
42 + session.response.should_not have_text(/OVER/)
43 end
43 end
44 end
44 end
45
45
46 it "should force users to log out when their contests change" do
46 it "should force users to log out when their contests change" do
47 - james_session = open_session
47 + session = open_session
48 - james_session.extend(MainSessionMethods)
48 + session.extend(MainSessionMethods)
49
49
50 - james_login_and_get_main_list(james_session)
50 + james_login_and_get_main_list(session)
51 - james_session.response.should_not have_text(/OVER/)
51 + session.response.should_not have_text(/OVER/)
52
52
53 Delorean.time_travel_to(190.minutes.since) do
53 Delorean.time_travel_to(190.minutes.since) do
54 - james_session.get_main_list
54 + session.get_main_list
55 - james_session.response.should have_text(/OVER/)
55 + session.response.should have_text(/OVER/)
56
56
57 admin_change_users_contest_to("james", @contest_b, true)
57 admin_change_users_contest_to("james", @contest_b, true)
58
58
59 - james_session.get '/main/list'
59 + session.get '/main/list'
60 - james_session.response.should_not render_template 'main/list'
60 + session.response.should_not render_template 'main/list'
61 - james_session.should be_redirect
61 + session.should be_redirect
62
62
63 Delorean.time_travel_to(200.minutes.since) do
63 Delorean.time_travel_to(200.minutes.since) do
64 - james_login_and_get_main_list(james_session)
64 + james_login_and_get_main_list(session)
65 - james_session.response.should_not have_text(/OVER/)
65 + session.response.should_not have_text(/OVER/)
66 + end
67 + end
66 end
68 end
69 +
70 + it "should maintain admin logged-in sessions even when their contests change" do
71 + session = open_session
72 + session.extend(MainSessionMethods)
73 +
74 + session.login('mary', 'goodbye')
75 + session.get_main_list
76 + session.response.should_not have_text(/OVER/)
77 +
78 + Delorean.time_travel_to(190.minutes.since) do
79 + session.get_main_list
80 + session.response.should have_text(/OVER/)
81 +
82 + admin_change_users_contest_to("mary", @contest_b, true)
83 +
84 + session.get '/main/list'
85 + session.response.should render_template 'main/list'
67 end
86 end
68 end
87 end
69
88
70 private
89 private
71
90
72 module MainSessionMethods
91 module MainSessionMethods
73 def login(login_name, password)
92 def login(login_name, password)
74 post '/login/login', :login => login_name, :password => password
93 post '/login/login', :login => login_name, :password => password
75 assert_redirected_to '/main/list'
94 assert_redirected_to '/main/list'
76 end
95 end
77
96
78 def get_main_list
97 def get_main_list
79 get '/main/list'
98 get '/main/list'
80 assert_template 'main/list'
99 assert_template 'main/list'
81 end
100 end
82
101
83 def get_main_list_and_assert_logout
102 def get_main_list_and_assert_logout
84 get '/main/list'
103 get '/main/list'
85 assert_redirected_to '/main'
104 assert_redirected_to '/main'
86 end
105 end
87 end
106 end
88
107
89 module ContestManagementSessionMethods
108 module ContestManagementSessionMethods
90 def change_users_contest_to(user_login_list, contest, reset_timer=false)
109 def change_users_contest_to(user_login_list, contest, reset_timer=false)
You need to be logged in to leave comments. Login now