Description:
update models to satisfy rails 4
Commit status:
[Not Reviewed]
References:
Comments:
0 Commit comments 0 Inline Comments
Unresolved TODOs:
There are no unresolved TODOs
Add another comment

r618:45e8321629ae - - 7 files changed: 12 inserted, 16 deleted

@@ -1,8 +1,8
1 class Contest < ActiveRecord::Base
1 class Contest < ActiveRecord::Base
2
2
3 has_and_belongs_to_many :users
3 has_and_belongs_to_many :users
4 has_and_belongs_to_many :problems
4 has_and_belongs_to_many :problems
5
5
6 - scope :enabled, :conditions => {:enabled => true}
6 + scope :enabled, -> { where(enabled: true) }
7
7
8 end
8 end
@@ -1,5 +1,4
1 class Login < ActiveRecord::Base
1 class Login < ActiveRecord::Base
2 belongs_to :user
2 belongs_to :user
3
3
4 - attr_accessible :ip_address, :logged_in_at, :user_id
5 end
4 end
@@ -1,133 +1,133
1 class Problem < ActiveRecord::Base
1 class Problem < ActiveRecord::Base
2
2
3 belongs_to :description
3 belongs_to :description
4 has_and_belongs_to_many :contests, :uniq => true
4 has_and_belongs_to_many :contests, :uniq => true
5 has_many :test_pairs, :dependent => :delete_all
5 has_many :test_pairs, :dependent => :delete_all
6 has_many :testcases, :dependent => :destroy
6 has_many :testcases, :dependent => :destroy
7
7
8 validates_presence_of :name
8 validates_presence_of :name
9 - validates_format_of :name, :with => /^\w+$/
9 + validates_format_of :name, :with => /\A\w+\z/
10 validates_presence_of :full_name
10 validates_presence_of :full_name
11
11
12 scope :available, :conditions => {:available => true}
12 scope :available, :conditions => {:available => true}
13
13
14 DEFAULT_TIME_LIMIT = 1
14 DEFAULT_TIME_LIMIT = 1
15 DEFAULT_MEMORY_LIMIT = 32
15 DEFAULT_MEMORY_LIMIT = 32
16
16
17 def self.find_available_problems
17 def self.find_available_problems
18 Problem.available.all(:order => "date_added DESC, name ASC")
18 Problem.available.all(:order => "date_added DESC, name ASC")
19 end
19 end
20
20
21 def self.create_from_import_form_params(params, old_problem=nil)
21 def self.create_from_import_form_params(params, old_problem=nil)
22 org_problem = old_problem || Problem.new
22 org_problem = old_problem || Problem.new
23 import_params, problem = Problem.extract_params_and_check(params,
23 import_params, problem = Problem.extract_params_and_check(params,
24 org_problem)
24 org_problem)
25
25
26 if !problem.errors.empty?
26 if !problem.errors.empty?
27 return problem, 'Error importing'
27 return problem, 'Error importing'
28 end
28 end
29
29
30 problem.full_score = 100
30 problem.full_score = 100
31 problem.date_added = Time.new
31 problem.date_added = Time.new
32 problem.test_allowed = true
32 problem.test_allowed = true
33 problem.output_only = false
33 problem.output_only = false
34 problem.available = false
34 problem.available = false
35
35
36 if not problem.save
36 if not problem.save
37 return problem, 'Error importing'
37 return problem, 'Error importing'
38 end
38 end
39
39
40 import_to_db = params.has_key? :import_to_db
40 import_to_db = params.has_key? :import_to_db
41
41
42 importer = TestdataImporter.new(problem)
42 importer = TestdataImporter.new(problem)
43
43
44 if not importer.import_from_file(import_params[:file],
44 if not importer.import_from_file(import_params[:file],
45 import_params[:time_limit],
45 import_params[:time_limit],
46 import_params[:memory_limit],
46 import_params[:memory_limit],
47 import_params[:checker_name],
47 import_params[:checker_name],
48 import_to_db)
48 import_to_db)
49 problem.errors.add(:base,'Import error.')
49 problem.errors.add(:base,'Import error.')
50 end
50 end
51
51
52 return problem, importer.log_msg
52 return problem, importer.log_msg
53 end
53 end
54
54
55 def self.download_file_basedir
55 def self.download_file_basedir
56 return "#{Rails.root}/data/tasks"
56 return "#{Rails.root}/data/tasks"
57 end
57 end
58
58
59 def get_submission_stat
59 def get_submission_stat
60 result = Hash.new
60 result = Hash.new
61 #total number of submission
61 #total number of submission
62 result[:total_sub] = Submission.where(problem_id: self.id).count
62 result[:total_sub] = Submission.where(problem_id: self.id).count
63 result[:attempted_user] = Submission.where(problem_id: self.id).group_by(:user_id)
63 result[:attempted_user] = Submission.where(problem_id: self.id).group_by(:user_id)
64 end
64 end
65
65
66 def long_name
66 def long_name
67 "[#{name}] #{full_name}"
67 "[#{name}] #{full_name}"
68 end
68 end
69
69
70 protected
70 protected
71
71
72 def self.to_i_or_default(st, default)
72 def self.to_i_or_default(st, default)
73 if st!=''
73 if st!=''
74 result = st.to_i
74 result = st.to_i
75 end
75 end
76 result ||= default
76 result ||= default
77 end
77 end
78
78
79 def self.to_f_or_default(st, default)
79 def self.to_f_or_default(st, default)
80 if st!=''
80 if st!=''
81 result = st.to_f
81 result = st.to_f
82 end
82 end
83 result ||= default
83 result ||= default
84 end
84 end
85
85
86 def self.extract_params_and_check(params, problem)
86 def self.extract_params_and_check(params, problem)
87 time_limit = Problem.to_f_or_default(params[:time_limit],
87 time_limit = Problem.to_f_or_default(params[:time_limit],
88 DEFAULT_TIME_LIMIT)
88 DEFAULT_TIME_LIMIT)
89 memory_limit = Problem.to_i_or_default(params[:memory_limit],
89 memory_limit = Problem.to_i_or_default(params[:memory_limit],
90 DEFAULT_MEMORY_LIMIT)
90 DEFAULT_MEMORY_LIMIT)
91
91
92 if time_limit<=0 or time_limit >60
92 if time_limit<=0 or time_limit >60
93 problem.errors.add(:base,'Time limit out of range.')
93 problem.errors.add(:base,'Time limit out of range.')
94 end
94 end
95
95
96 if memory_limit==0 and params[:memory_limit]!='0'
96 if memory_limit==0 and params[:memory_limit]!='0'
97 problem.errors.add(:base,'Memory limit format errors.')
97 problem.errors.add(:base,'Memory limit format errors.')
98 elsif memory_limit<=0 or memory_limit >512
98 elsif memory_limit<=0 or memory_limit >512
99 problem.errors.add(:base,'Memory limit out of range.')
99 problem.errors.add(:base,'Memory limit out of range.')
100 end
100 end
101
101
102 if params[:file]==nil or params[:file]==''
102 if params[:file]==nil or params[:file]==''
103 problem.errors.add(:base,'No testdata file.')
103 problem.errors.add(:base,'No testdata file.')
104 end
104 end
105
105
106 checker_name = 'text'
106 checker_name = 'text'
107 if ['text','float'].include? params[:checker]
107 if ['text','float'].include? params[:checker]
108 checker_name = params[:checker]
108 checker_name = params[:checker]
109 end
109 end
110
110
111 file = params[:file]
111 file = params[:file]
112
112
113 if !problem.errors.empty?
113 if !problem.errors.empty?
114 return nil, problem
114 return nil, problem
115 end
115 end
116
116
117 problem.name = params[:name]
117 problem.name = params[:name]
118 if params[:full_name]!=''
118 if params[:full_name]!=''
119 problem.full_name = params[:full_name]
119 problem.full_name = params[:full_name]
120 else
120 else
121 problem.full_name = params[:name]
121 problem.full_name = params[:name]
122 end
122 end
123
123
124 return [{
124 return [{
125 :time_limit => time_limit,
125 :time_limit => time_limit,
126 :memory_limit => memory_limit,
126 :memory_limit => memory_limit,
127 :file => file,
127 :file => file,
128 :checker_name => checker_name
128 :checker_name => checker_name
129 },
129 },
130 problem]
130 problem]
131 end
131 end
132
132
133 end
133 end
@@ -1,3 +1,3
1 class SubmissionViewLog < ActiveRecord::Base
1 class SubmissionViewLog < ActiveRecord::Base
2 - attr_accessible :submission_id, :user_id
2 + #attr_accessible :submission_id, :user_id
3 end
3 end
@@ -1,157 +1,156
1 #
1 #
2 # A TestRequest is a composition of submission with user's testdata.
2 # A TestRequest is a composition of submission with user's testdata.
3 #
3 #
4 # Note about TestRequest#problem: Usually, A TestRequest has to be
4 # Note about TestRequest#problem: Usually, A TestRequest has to be
5 # associated with a problem, so that execution environment can be
5 # associated with a problem, so that execution environment can be
6 # determined. However, to be more flexible, we have to ensure that
6 # determined. However, to be more flexible, we have to ensure that
7 # it works as well with problem=nil. In this case, we shall provide
7 # it works as well with problem=nil. In this case, we shall provide
8 # a "default" execution environment for it. This can be done
8 # a "default" execution environment for it. This can be done
9 # seamlessly by using TestRequest#problem_name or
9 # seamlessly by using TestRequest#problem_name or
10 # TestRequest#name_of(problem) when retrieving the name of the
10 # TestRequest#name_of(problem) when retrieving the name of the
11 # problem: #name_of would return problem.name when problem!=nil and
11 # problem: #name_of would return problem.name when problem!=nil and
12 # it would return "default" when problem=nil, #problem_name just
12 # it would return "default" when problem=nil, #problem_name just
13 # call #name_of.
13 # call #name_of.
14 #
14 #
15
15
16 require 'fileutils'
16 require 'fileutils'
17
17
18 class TestRequest < Task
18 class TestRequest < Task
19 -
19 + self.table_name = "test_requests"
20 - set_table_name "test_requests"
21
20
22 belongs_to :user
21 belongs_to :user
23 belongs_to :problem
22 belongs_to :problem
24 belongs_to :submission
23 belongs_to :submission
25
24
26 validates_presence_of :submission
25 validates_presence_of :submission
27 validate :must_have_valid_problem
26 validate :must_have_valid_problem
28
27
29 def problem_name
28 def problem_name
30 TestRequest.name_of(self.problem)
29 TestRequest.name_of(self.problem)
31 end
30 end
32
31
33 def language
32 def language
34 self.submission.language
33 self.submission.language
35 end
34 end
36
35
37 def self.get_inqueue_and_change_status(status)
36 def self.get_inqueue_and_change_status(status)
38 # since there will be only one grader grading TestRequest
37 # since there will be only one grader grading TestRequest
39 # we do not need locking (hopefully)
38 # we do not need locking (hopefully)
40
39
41 test_request = TestRequest.find(:first,
40 test_request = TestRequest.find(:first,
42 :order => "created_at",
41 :order => "created_at",
43 :conditions => {:status=> Task::STATUS_INQUEUE})
42 :conditions => {:status=> Task::STATUS_INQUEUE})
44 if test_request!=nil
43 if test_request!=nil
45 test_request.status = status
44 test_request.status = status
46 test_request.save!
45 test_request.save!
47 end
46 end
48
47
49 test_request
48 test_request
50 end
49 end
51
50
52 # interfacing with form
51 # interfacing with form
53 def self.new_from_form_params(user,params)
52 def self.new_from_form_params(user,params)
54 test_request = TestRequest.new
53 test_request = TestRequest.new
55 test_request.user = user
54 test_request.user = user
56 begin
55 begin
57 problem = Problem.find(params[:problem_id])
56 problem = Problem.find(params[:problem_id])
58 rescue ActiveRecord::RecordNotFound
57 rescue ActiveRecord::RecordNotFound
59 problem = nil
58 problem = nil
60 end
59 end
61 test_request.problem = problem
60 test_request.problem = problem
62 if problem!=nil
61 if problem!=nil
63 test_request.submission =
62 test_request.submission =
64 Submission.find_by_user_problem_number(user.id,
63 Submission.find_by_user_problem_number(user.id,
65 problem.id,
64 problem.id,
66 params[:submission_number])
65 params[:submission_number])
67 else
66 else
68 test_request.submission = nil
67 test_request.submission = nil
69 end
68 end
70
69
71 # checks if the user submits any input file
70 # checks if the user submits any input file
72 if params[:input_file]==nil or params[:input_file]==""
71 if params[:input_file]==nil or params[:input_file]==""
73 test_request.errors.add(:base,"No input submitted.")
72 test_request.errors.add(:base,"No input submitted.")
74 test_request.input_file_name = nil
73 test_request.input_file_name = nil
75 else
74 else
76 test_request.input_file_name = save_input_file(params[:input_file], user, problem)
75 test_request.input_file_name = save_input_file(params[:input_file], user, problem)
77 if test_request.input_file_name == nil
76 if test_request.input_file_name == nil
78 test_request.errors.adds(:base,"No input submitted.")
77 test_request.errors.adds(:base,"No input submitted.")
79 end
78 end
80 if params[:additional_file]!=nil and params[:additional_file]!=""
79 if params[:additional_file]!=nil and params[:additional_file]!=""
81 save_additional_file(params[:additional_file],
80 save_additional_file(params[:additional_file],
82 "#{test_request.input_file_name}.files")
81 "#{test_request.input_file_name}.files")
83 end
82 end
84 end
83 end
85 test_request.submitted_at = Time.new.gmtime
84 test_request.submitted_at = Time.new.gmtime
86 test_request.status_inqueue
85 test_request.status_inqueue
87 test_request
86 test_request
88 end
87 end
89
88
90 protected
89 protected
91
90
92 def self.name_of(problem)
91 def self.name_of(problem)
93 if problem!=nil
92 if problem!=nil
94 problem.name
93 problem.name
95 else
94 else
96 "default"
95 "default"
97 end
96 end
98 end
97 end
99
98
100 def self.random_input_file_name(user,problem)
99 def self.random_input_file_name(user,problem)
101 problem_name = TestRequest.name_of(problem)
100 problem_name = TestRequest.name_of(problem)
102 begin
101 begin
103 tmpname = TEST_REQUEST_INPUT_FILE_DIR + "/#{user.login}/#{problem_name}/#{rand(10000)}"
102 tmpname = TEST_REQUEST_INPUT_FILE_DIR + "/#{user.login}/#{problem_name}/#{rand(10000)}"
104 end while File.exists?(tmpname)
103 end while File.exists?(tmpname)
105 tmpname
104 tmpname
106 end
105 end
107
106
108 def self.save_input_file(tempfile, user, problem)
107 def self.save_input_file(tempfile, user, problem)
109 new_file_name = random_input_file_name(user,problem)
108 new_file_name = random_input_file_name(user,problem)
110 dirname = File.dirname(new_file_name)
109 dirname = File.dirname(new_file_name)
111 FileUtils.mkdir_p(File.dirname(new_file_name)) if !File.exists?(dirname)
110 FileUtils.mkdir_p(File.dirname(new_file_name)) if !File.exists?(dirname)
112
111
113 # when the user did not submit any file
112 # when the user did not submit any file
114 return nil if tempfile==""
113 return nil if tempfile==""
115
114
116 if tempfile.instance_of?(Tempfile)
115 if tempfile.instance_of?(Tempfile)
117 tempfile.close
116 tempfile.close
118 FileUtils.move(tempfile.path,new_file_name)
117 FileUtils.move(tempfile.path,new_file_name)
119 else
118 else
120 File.open(new_file_name, "wb") do |f|
119 File.open(new_file_name, "wb") do |f|
121 f.write(tempfile.read)
120 f.write(tempfile.read)
122 end
121 end
123 end
122 end
124 new_file_name
123 new_file_name
125 end
124 end
126
125
127 def self.save_additional_file(tempfile,dir)
126 def self.save_additional_file(tempfile,dir)
128 new_file_name = "#{dir}/#{tempfile.original_filename}"
127 new_file_name = "#{dir}/#{tempfile.original_filename}"
129 dirname = File.dirname(new_file_name)
128 dirname = File.dirname(new_file_name)
130 FileUtils.mkdir_p(File.dirname(new_file_name)) if !File.exists?(dirname)
129 FileUtils.mkdir_p(File.dirname(new_file_name)) if !File.exists?(dirname)
131
130
132 # when the user did not submit any file
131 # when the user did not submit any file
133 return nil if tempfile==""
132 return nil if tempfile==""
134
133
135 if tempfile.instance_of?(Tempfile)
134 if tempfile.instance_of?(Tempfile)
136 tempfile.close
135 tempfile.close
137 FileUtils.move(tempfile.path,new_file_name)
136 FileUtils.move(tempfile.path,new_file_name)
138 else
137 else
139 File.open(new_file_name, "wb") do |f|
138 File.open(new_file_name, "wb") do |f|
140 f.write(tempfile.read)
139 f.write(tempfile.read)
141 end
140 end
142 end
141 end
143 new_file_name
142 new_file_name
144 end
143 end
145
144
146 #
145 #
147 # validations
146 # validations
148 #
147 #
149 def must_have_valid_problem
148 def must_have_valid_problem
150 if problem==nil
149 if problem==nil
151 errors.add('problem',"must be specified.")
150 errors.add('problem',"must be specified.")
152 elsif (!problem.available) and (self.new_record?)
151 elsif (!problem.available) and (self.new_record?)
153 errors.add('problem',"must be valid.")
152 errors.add('problem',"must be valid.")
154 end
153 end
155 end
154 end
156
155
157 end
156 end
@@ -1,4 +1,4
1 class Testcase < ActiveRecord::Base
1 class Testcase < ActiveRecord::Base
2 belongs_to :problem
2 belongs_to :problem
3 - attr_accessible :group, :input, :num, :score, :sol
3 + #attr_accessible :group, :input, :num, :score, :sol
4 end
4 end
@@ -1,381 +1,379
1 require 'digest/sha1'
1 require 'digest/sha1'
2 require 'net/pop'
2 require 'net/pop'
3 require 'net/https'
3 require 'net/https'
4 require 'net/http'
4 require 'net/http'
5 require 'json'
5 require 'json'
6
6
7 class User < ActiveRecord::Base
7 class User < ActiveRecord::Base
8
8
9 has_and_belongs_to_many :roles
9 has_and_belongs_to_many :roles
10
10
11 - has_many :test_requests, :order => "submitted_at DESC"
11 + has_many :test_requests, -> {order(submitted_at: DESC)}
12
12
13 - has_many :messages,
13 + has_many :messages, -> { order(created_at: DESC) },
14 :class_name => "Message",
14 :class_name => "Message",
15 - :foreign_key => "sender_id",
15 + :foreign_key => "sender_id"
16 - :order => 'created_at DESC'
17
16
18 - has_many :replied_messages,
17 + has_many :replied_messages, -> { order(created_at: DESC) },
19 :class_name => "Message",
18 :class_name => "Message",
20 - :foreign_key => "receiver_id",
19 + :foreign_key => "receiver_id"
21 - :order => 'created_at DESC'
22
20
23 has_one :contest_stat, :class_name => "UserContestStat", :dependent => :destroy
21 has_one :contest_stat, :class_name => "UserContestStat", :dependent => :destroy
24
22
25 belongs_to :site
23 belongs_to :site
26 belongs_to :country
24 belongs_to :country
27
25
28 - has_and_belongs_to_many :contests, :uniq => true, :order => 'name'
26 + has_and_belongs_to_many :contests, -> { order(:name); uniq}
29
27
30 - scope :activated_users, :conditions => {:activated => true}
28 + scope :activated_users, -> {where activated: true}
31
29
32 validates_presence_of :login
30 validates_presence_of :login
33 validates_uniqueness_of :login
31 validates_uniqueness_of :login
34 validates_format_of :login, :with => /\A[\_A-Za-z0-9]+\z/
32 validates_format_of :login, :with => /\A[\_A-Za-z0-9]+\z/
35 validates_length_of :login, :within => 3..30
33 validates_length_of :login, :within => 3..30
36
34
37 validates_presence_of :full_name
35 validates_presence_of :full_name
38 validates_length_of :full_name, :minimum => 1
36 validates_length_of :full_name, :minimum => 1
39
37
40 validates_presence_of :password, :if => :password_required?
38 validates_presence_of :password, :if => :password_required?
41 validates_length_of :password, :within => 4..20, :if => :password_required?
39 validates_length_of :password, :within => 4..20, :if => :password_required?
42 validates_confirmation_of :password, :if => :password_required?
40 validates_confirmation_of :password, :if => :password_required?
43
41
44 validates_format_of :email,
42 validates_format_of :email,
45 :with => /\A([^@\s]+)@((?:[-a-z0-9]+\.)+[a-z]{2,})\Z/i,
43 :with => /\A([^@\s]+)@((?:[-a-z0-9]+\.)+[a-z]{2,})\Z/i,
46 :if => :email_validation?
44 :if => :email_validation?
47 validate :uniqueness_of_email_from_activated_users,
45 validate :uniqueness_of_email_from_activated_users,
48 :if => :email_validation?
46 :if => :email_validation?
49 validate :enough_time_interval_between_same_email_registrations,
47 validate :enough_time_interval_between_same_email_registrations,
50 :if => :email_validation?
48 :if => :email_validation?
51
49
52 # these are for ytopc
50 # these are for ytopc
53 # disable for now
51 # disable for now
54 #validates_presence_of :province
52 #validates_presence_of :province
55
53
56 attr_accessor :password
54 attr_accessor :password
57
55
58 before_save :encrypt_new_password
56 before_save :encrypt_new_password
59 before_save :assign_default_site
57 before_save :assign_default_site
60 before_save :assign_default_contest
58 before_save :assign_default_contest
61
59
62 # this is for will_paginate
60 # this is for will_paginate
63 cattr_reader :per_page
61 cattr_reader :per_page
64 @@per_page = 50
62 @@per_page = 50
65
63
66 def self.authenticate(login, password)
64 def self.authenticate(login, password)
67 user = find_by_login(login)
65 user = find_by_login(login)
68 if user
66 if user
69 return user if user.authenticated?(password)
67 return user if user.authenticated?(password)
70 if user.authenticated_by_cucas?(password) or user.authenticated_by_pop3?(password)
68 if user.authenticated_by_cucas?(password) or user.authenticated_by_pop3?(password)
71 user.password = password
69 user.password = password
72 user.save
70 user.save
73 return user
71 return user
74 end
72 end
75 end
73 end
76 end
74 end
77
75
78 def authenticated?(password)
76 def authenticated?(password)
79 if self.activated
77 if self.activated
80 hashed_password == User.encrypt(password,self.salt)
78 hashed_password == User.encrypt(password,self.salt)
81 else
79 else
82 false
80 false
83 end
81 end
84 end
82 end
85
83
86 def authenticated_by_pop3?(password)
84 def authenticated_by_pop3?(password)
87 Net::POP3.enable_ssl
85 Net::POP3.enable_ssl
88 pop = Net::POP3.new('pops.it.chula.ac.th')
86 pop = Net::POP3.new('pops.it.chula.ac.th')
89 authen = true
87 authen = true
90 begin
88 begin
91 pop.start(login, password)
89 pop.start(login, password)
92 pop.finish
90 pop.finish
93 return true
91 return true
94 rescue
92 rescue
95 return false
93 return false
96 end
94 end
97 end
95 end
98
96
99 def authenticated_by_cucas?(password)
97 def authenticated_by_cucas?(password)
100 url = URI.parse('https://www.cas.chula.ac.th/cas/api/?q=studentAuthenticate')
98 url = URI.parse('https://www.cas.chula.ac.th/cas/api/?q=studentAuthenticate')
101 appid = '41508763e340d5858c00f8c1a0f5a2bb'
99 appid = '41508763e340d5858c00f8c1a0f5a2bb'
102 appsecret ='d9cbb5863091dbe186fded85722a1e31'
100 appsecret ='d9cbb5863091dbe186fded85722a1e31'
103 post_args = {
101 post_args = {
104 'appid' => appid,
102 'appid' => appid,
105 'appsecret' => appsecret,
103 'appsecret' => appsecret,
106 'username' => login,
104 'username' => login,
107 'password' => password
105 'password' => password
108 }
106 }
109
107
110 #simple call
108 #simple call
111 begin
109 begin
112 http = Net::HTTP.new('www.cas.chula.ac.th', 443)
110 http = Net::HTTP.new('www.cas.chula.ac.th', 443)
113 http.use_ssl = true
111 http.use_ssl = true
114 http.verify_mode = OpenSSL::SSL::VERIFY_NONE
112 http.verify_mode = OpenSSL::SSL::VERIFY_NONE
115 result = [ ]
113 result = [ ]
116 http.start do |http|
114 http.start do |http|
117 req = Net::HTTP::Post.new('/cas/api/?q=studentAuthenticate')
115 req = Net::HTTP::Post.new('/cas/api/?q=studentAuthenticate')
118 param = "appid=#{appid}&appsecret=#{appsecret}&username=#{login}&password=#{password}"
116 param = "appid=#{appid}&appsecret=#{appsecret}&username=#{login}&password=#{password}"
119 resp = http.request(req,param)
117 resp = http.request(req,param)
120 result = JSON.parse resp.body
118 result = JSON.parse resp.body
121 end
119 end
122 return true if result["type"] == "beanStudent"
120 return true if result["type"] == "beanStudent"
123 rescue => e
121 rescue => e
124 return false
122 return false
125 end
123 end
126 return false
124 return false
127 end
125 end
128
126
129 def admin?
127 def admin?
130 self.roles.detect {|r| r.name == 'admin' }
128 self.roles.detect {|r| r.name == 'admin' }
131 end
129 end
132
130
133 def email_for_editing
131 def email_for_editing
134 if self.email==nil
132 if self.email==nil
135 "(unknown)"
133 "(unknown)"
136 elsif self.email==''
134 elsif self.email==''
137 "(blank)"
135 "(blank)"
138 else
136 else
139 self.email
137 self.email
140 end
138 end
141 end
139 end
142
140
143 def email_for_editing=(e)
141 def email_for_editing=(e)
144 self.email=e
142 self.email=e
145 end
143 end
146
144
147 def alias_for_editing
145 def alias_for_editing
148 if self.alias==nil
146 if self.alias==nil
149 "(unknown)"
147 "(unknown)"
150 elsif self.alias==''
148 elsif self.alias==''
151 "(blank)"
149 "(blank)"
152 else
150 else
153 self.alias
151 self.alias
154 end
152 end
155 end
153 end
156
154
157 def alias_for_editing=(e)
155 def alias_for_editing=(e)
158 self.alias=e
156 self.alias=e
159 end
157 end
160
158
161 def activation_key
159 def activation_key
162 if self.hashed_password==nil
160 if self.hashed_password==nil
163 encrypt_new_password
161 encrypt_new_password
164 end
162 end
165 Digest::SHA1.hexdigest(self.hashed_password)[0..7]
163 Digest::SHA1.hexdigest(self.hashed_password)[0..7]
166 end
164 end
167
165
168 def verify_activation_key(key)
166 def verify_activation_key(key)
169 key == activation_key
167 key == activation_key
170 end
168 end
171
169
172 def self.random_password(length=5)
170 def self.random_password(length=5)
173 chars = 'abcdefghjkmnopqrstuvwxyz'
171 chars = 'abcdefghjkmnopqrstuvwxyz'
174 password = ''
172 password = ''
175 length.times { password << chars[rand(chars.length - 1)] }
173 length.times { password << chars[rand(chars.length - 1)] }
176 password
174 password
177 end
175 end
178
176
179 def self.find_non_admin_with_prefix(prefix='')
177 def self.find_non_admin_with_prefix(prefix='')
180 users = User.find(:all)
178 users = User.find(:all)
181 return users.find_all { |u| !(u.admin?) and u.login.index(prefix)==0 }
179 return users.find_all { |u| !(u.admin?) and u.login.index(prefix)==0 }
182 end
180 end
183
181
184 # Contest information
182 # Contest information
185
183
186 def self.find_users_with_no_contest()
184 def self.find_users_with_no_contest()
187 users = User.find(:all)
185 users = User.find(:all)
188 return users.find_all { |u| u.contests.length == 0 }
186 return users.find_all { |u| u.contests.length == 0 }
189 end
187 end
190
188
191
189
192 def contest_time_left
190 def contest_time_left
193 if GraderConfiguration.contest_mode?
191 if GraderConfiguration.contest_mode?
194 return nil if site==nil
192 return nil if site==nil
195 return site.time_left
193 return site.time_left
196 elsif GraderConfiguration.indv_contest_mode?
194 elsif GraderConfiguration.indv_contest_mode?
197 time_limit = GraderConfiguration.contest_time_limit
195 time_limit = GraderConfiguration.contest_time_limit
198 if time_limit == nil
196 if time_limit == nil
199 return nil
197 return nil
200 end
198 end
201 if contest_stat==nil or contest_stat.started_at==nil
199 if contest_stat==nil or contest_stat.started_at==nil
202 return (Time.now.gmtime + time_limit) - Time.now.gmtime
200 return (Time.now.gmtime + time_limit) - Time.now.gmtime
203 else
201 else
204 finish_time = contest_stat.started_at + time_limit
202 finish_time = contest_stat.started_at + time_limit
205 current_time = Time.now.gmtime
203 current_time = Time.now.gmtime
206 if current_time > finish_time
204 if current_time > finish_time
207 return 0
205 return 0
208 else
206 else
209 return finish_time - current_time
207 return finish_time - current_time
210 end
208 end
211 end
209 end
212 else
210 else
213 return nil
211 return nil
214 end
212 end
215 end
213 end
216
214
217 def contest_finished?
215 def contest_finished?
218 if GraderConfiguration.contest_mode?
216 if GraderConfiguration.contest_mode?
219 return false if site==nil
217 return false if site==nil
220 return site.finished?
218 return site.finished?
221 elsif GraderConfiguration.indv_contest_mode?
219 elsif GraderConfiguration.indv_contest_mode?
222 return false if self.contest_stat(true)==nil
220 return false if self.contest_stat(true)==nil
223 return contest_time_left == 0
221 return contest_time_left == 0
224 else
222 else
225 return false
223 return false
226 end
224 end
227 end
225 end
228
226
229 def contest_started?
227 def contest_started?
230 if GraderConfiguration.indv_contest_mode?
228 if GraderConfiguration.indv_contest_mode?
231 stat = self.contest_stat
229 stat = self.contest_stat
232 return ((stat != nil) and (stat.started_at != nil))
230 return ((stat != nil) and (stat.started_at != nil))
233 elsif GraderConfiguration.contest_mode?
231 elsif GraderConfiguration.contest_mode?
234 return true if site==nil
232 return true if site==nil
235 return site.started
233 return site.started
236 else
234 else
237 return true
235 return true
238 end
236 end
239 end
237 end
240
238
241 def update_start_time
239 def update_start_time
242 stat = self.contest_stat
240 stat = self.contest_stat
243 if stat.nil? or stat.started_at.nil?
241 if stat.nil? or stat.started_at.nil?
244 stat ||= UserContestStat.new(:user => self)
242 stat ||= UserContestStat.new(:user => self)
245 stat.started_at = Time.now.gmtime
243 stat.started_at = Time.now.gmtime
246 stat.save
244 stat.save
247 end
245 end
248 end
246 end
249
247
250 def problem_in_user_contests?(problem)
248 def problem_in_user_contests?(problem)
251 problem_contests = problem.contests.all
249 problem_contests = problem.contests.all
252
250
253 if problem_contests.length == 0 # this is public contest
251 if problem_contests.length == 0 # this is public contest
254 return true
252 return true
255 end
253 end
256
254
257 contests.each do |contest|
255 contests.each do |contest|
258 if problem_contests.find {|c| c.id == contest.id }
256 if problem_contests.find {|c| c.id == contest.id }
259 return true
257 return true
260 end
258 end
261 end
259 end
262 return false
260 return false
263 end
261 end
264
262
265 def available_problems_group_by_contests
263 def available_problems_group_by_contests
266 contest_problems = []
264 contest_problems = []
267 pin = {}
265 pin = {}
268 contests.enabled.each do |contest|
266 contests.enabled.each do |contest|
269 available_problems = contest.problems.available
267 available_problems = contest.problems.available
270 contest_problems << {
268 contest_problems << {
271 :contest => contest,
269 :contest => contest,
272 :problems => available_problems
270 :problems => available_problems
273 }
271 }
274 available_problems.each {|p| pin[p.id] = true}
272 available_problems.each {|p| pin[p.id] = true}
275 end
273 end
276 other_avaiable_problems = Problem.available.find_all {|p| pin[p.id]==nil and p.contests.length==0}
274 other_avaiable_problems = Problem.available.find_all {|p| pin[p.id]==nil and p.contests.length==0}
277 contest_problems << {
275 contest_problems << {
278 :contest => nil,
276 :contest => nil,
279 :problems => other_avaiable_problems
277 :problems => other_avaiable_problems
280 }
278 }
281 return contest_problems
279 return contest_problems
282 end
280 end
283
281
284 def available_problems
282 def available_problems
285 if not GraderConfiguration.multicontests?
283 if not GraderConfiguration.multicontests?
286 return Problem.find_available_problems
284 return Problem.find_available_problems
287 else
285 else
288 contest_problems = []
286 contest_problems = []
289 pin = {}
287 pin = {}
290 contests.enabled.each do |contest|
288 contests.enabled.each do |contest|
291 contest.problems.available.each do |problem|
289 contest.problems.available.each do |problem|
292 if not pin.has_key? problem.id
290 if not pin.has_key? problem.id
293 contest_problems << problem
291 contest_problems << problem
294 end
292 end
295 pin[problem.id] = true
293 pin[problem.id] = true
296 end
294 end
297 end
295 end
298 other_avaiable_problems = Problem.available.find_all {|p| pin[p.id]==nil and p.contests.length==0}
296 other_avaiable_problems = Problem.available.find_all {|p| pin[p.id]==nil and p.contests.length==0}
299 return contest_problems + other_avaiable_problems
297 return contest_problems + other_avaiable_problems
300 end
298 end
301 end
299 end
302
300
303 def can_view_problem?(problem)
301 def can_view_problem?(problem)
304 if not GraderConfiguration.multicontests?
302 if not GraderConfiguration.multicontests?
305 return problem.available
303 return problem.available
306 else
304 else
307 return problem_in_user_contests? problem
305 return problem_in_user_contests? problem
308 end
306 end
309 end
307 end
310
308
311 def self.clear_last_login
309 def self.clear_last_login
312 User.update_all(:last_ip => nil)
310 User.update_all(:last_ip => nil)
313 end
311 end
314
312
315 protected
313 protected
316 def encrypt_new_password
314 def encrypt_new_password
317 return if password.blank?
315 return if password.blank?
318 self.salt = (10+rand(90)).to_s
316 self.salt = (10+rand(90)).to_s
319 self.hashed_password = User.encrypt(self.password,self.salt)
317 self.hashed_password = User.encrypt(self.password,self.salt)
320 end
318 end
321
319
322 def assign_default_site
320 def assign_default_site
323 # have to catch error when migrating (because self.site is not available).
321 # have to catch error when migrating (because self.site is not available).
324 begin
322 begin
325 if self.site==nil
323 if self.site==nil
326 self.site = Site.find_by_name('default')
324 self.site = Site.find_by_name('default')
327 if self.site==nil
325 if self.site==nil
328 self.site = Site.find(1) # when 'default has be renamed'
326 self.site = Site.find(1) # when 'default has be renamed'
329 end
327 end
330 end
328 end
331 rescue
329 rescue
332 end
330 end
333 end
331 end
334
332
335 def assign_default_contest
333 def assign_default_contest
336 # have to catch error when migrating (because self.site is not available).
334 # have to catch error when migrating (because self.site is not available).
337 begin
335 begin
338 if self.contests.length == 0
336 if self.contests.length == 0
339 default_contest = Contest.find_by_name(GraderConfiguration['contest.default_contest_name'])
337 default_contest = Contest.find_by_name(GraderConfiguration['contest.default_contest_name'])
340 if default_contest
338 if default_contest
341 self.contests = [default_contest]
339 self.contests = [default_contest]
342 end
340 end
343 end
341 end
344 rescue
342 rescue
345 end
343 end
346 end
344 end
347
345
348 def password_required?
346 def password_required?
349 self.hashed_password.blank? || !self.password.blank?
347 self.hashed_password.blank? || !self.password.blank?
350 end
348 end
351
349
352 def self.encrypt(string,salt)
350 def self.encrypt(string,salt)
353 Digest::SHA1.hexdigest(salt + string)
351 Digest::SHA1.hexdigest(salt + string)
354 end
352 end
355
353
356 def uniqueness_of_email_from_activated_users
354 def uniqueness_of_email_from_activated_users
357 user = User.activated_users.find_by_email(self.email)
355 user = User.activated_users.find_by_email(self.email)
358 if user and (user.login != self.login)
356 if user and (user.login != self.login)
359 self.errors.add(:base,"Email has already been taken")
357 self.errors.add(:base,"Email has already been taken")
360 end
358 end
361 end
359 end
362
360
363 def enough_time_interval_between_same_email_registrations
361 def enough_time_interval_between_same_email_registrations
364 return if !self.new_record?
362 return if !self.new_record?
365 return if self.activated
363 return if self.activated
366 open_user = User.find_by_email(self.email,
364 open_user = User.find_by_email(self.email,
367 :order => 'created_at DESC')
365 :order => 'created_at DESC')
368 if open_user and open_user.created_at and
366 if open_user and open_user.created_at and
369 (open_user.created_at > Time.now.gmtime - 5.minutes)
367 (open_user.created_at > Time.now.gmtime - 5.minutes)
370 self.errors.add(:base,"There are already unactivated registrations with this e-mail address (please wait for 5 minutes)")
368 self.errors.add(:base,"There are already unactivated registrations with this e-mail address (please wait for 5 minutes)")
371 end
369 end
372 end
370 end
373
371
374 def email_validation?
372 def email_validation?
375 begin
373 begin
376 return VALIDATE_USER_EMAILS
374 return VALIDATE_USER_EMAILS
377 rescue
375 rescue
378 return false
376 return false
379 end
377 end
380 end
378 end
381 end
379 end
You need to be logged in to leave comments. Login now