1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
|
# Copyright (C) 2014 Andrew Murrell
# Copyright (C) 2014 Davis Webb
# Copyright (C) 2014 Guntas Grewal
# Copyright (C) 2014 Luke Shumaker
# Copyright (C) 2014 Nathaniel Foy
# Copyright (C) 2014 Tomer Kimia
#
# This file is part of Leaguer.
#
# Leaguer is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# Leaguer is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Affero General Public License for more details.
#
# You should have received a copy of the Affero GNU General Public License
# along with Leaguer. If not, see <http://www.gnu.org/licenses/>.
class Tournament < ActiveRecord::Base
belongs_to :game
has_many :tournament_stages
# Don't validate presence of stages; sadly, it seems to break things
#validates_presence_of :tournament_stages
alias_attribute :stages, :tournament_stages
has_many :brackets
has_many :tournament_settings
has_and_belongs_to_many :players, class_name: "User", association_foreign_key: "player_id", join_table: "players_tournaments"
has_and_belongs_to_many :hosts, class_name: "User", association_foreign_key: "host_id", join_table: "hosts_tournaments"
validates_presence_of :hosts
validates_presence_of :game
before_save { self.status ||= 0 }
validates(:name,
presence: true,
length: {minimum: 5},
uniqueness: {case_sensitive: true})
validates(:min_players_per_team,
presence: true,
numericality: {
only_integer: true,
less_than_or_equal_to: :max_players_per_team,
})
validates(:max_players_per_team,
presence: true,
numericality: {
only_integer: true,
greater_than_or_equal_to: :min_players_per_team,
})
validates(:min_teams_per_match,
presence: true,
numericality: {
only_integer: true,
less_than_or_equal_to: :max_teams_per_match,
})
validates(:max_teams_per_match,
presence: true,
numericality: {
only_integer: true,
greater_than_or_equal_to: :min_teams_per_match,
})
validate :validate_scoring_method
def validate_scoring_method
(not self.scoring_method.try(:empty?)) and (scoring_methods.include? scoring_method)
end
def owned_by?(user)
self.hosts.include?(user)
end
# Settings #################################################################
def settings
@settings ||= Settings.new(self)
end
def settings=(setting)
setting.each do |key, value|
value = false if value == "0"
settings[key] = value
end
end
class Settings
def initialize(tournament)
@tournament = tournament
end
def [](setting_name)
tournament_setting = @tournament.tournament_settings.find{|s|s.name==setting_name}
if tournament_setting.nil?
return nil
else
return tournament_setting.value
end
end
def []=(setting_name, val)
tournament_setting = @tournament.tournament_settings.find{|s|s.name==setting_name}
if tournament_setting.nil?
game_setting = @tournament.game.settings.find_by_name(setting_name)
@tournament.tournament_settings.build(name: setting_name, value: val,
vartype: game_setting.vartype,
type_opt: game_setting.type_opt,
description: game_setting.description,
display_order: game_setting.display_order)
else
tournament_setting.value = val
end
end
def keys
@tournament.tournament_settings.all.collect { |x| x.name }
end
def empty?() keys.empty? end
def count() keys.count end
def length() count end
def size() count end
def method_missing(name, *args)
if name.to_s.ends_with?('=')
self[name.to_s.sub(/=$/, '').to_s] = args.first
else
return self[name.to_s]
end
end
end
# Joining/Leaving ##########################################################
def joinable_by?(user)
return (status==0 and user.can?(:join_tournament) and !players.include?(user))
end
def join(user)
unless joinable_by?(user)
return false
end
players.push(user)
end
def leave(user)
if players.include?(user) && status == 0
players.delete(user)
end
end
# Configured methods #######################################################
def scoring
@scoring ||= "Scoring::#{self.scoring_method.camelcase}".constantize
end
# Options for configured methods/modules ###################################
# We're conflicted about whether these should be `self.` or not. ###########
def self.scoring_methods
make_methods "scoring"
end
def scoring_methods
self.class.scoring_methods
end
def sampling_methods
self.class.make_methods("sampling").select do |name|
"Sampling::#{name.camelcase}".constantize.works_with?(self.game)
end
end
def self.scheduling_methods
make_methods "scheduling"
end
def scheduling_methods
self.class.scheduling_methods
end
def self.seeding_methods
make_methods "seeding"
end
def seeding_methods
self.class.seeding_methods
end
private
def self.make_methods(dir)
@methods ||= {}
if @methods[dir].nil? or Rails.env.development?
@methods[dir] = Dir.glob("#{Rails.root}/lib/#{dir}/*.rb").map{|filename| File.basename(filename, ".rb") }
end
return @methods[dir]
end
end
|