sportdb-models 1.10.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.gemtest +0 -0
- data/HISTORY.md +21 -0
- data/Manifest.txt +142 -0
- data/README.md +28 -0
- data/Rakefile +59 -0
- data/config/fixtures/de.yml +46 -0
- data/config/fixtures/en.yml +54 -0
- data/config/fixtures/es.yml +48 -0
- data/config/fixtures/fr.yml +53 -0
- data/config/fixtures/it.yml +55 -0
- data/config/fixtures/pt.yml +46 -0
- data/config/fixtures/ro.yml +55 -0
- data/data/seasons.txt +74 -0
- data/data/setups/all.txt +5 -0
- data/lib/sportdb/calc.rb +279 -0
- data/lib/sportdb/deleter.rb +52 -0
- data/lib/sportdb/finders/date.rb +374 -0
- data/lib/sportdb/finders/goals.rb +260 -0
- data/lib/sportdb/finders/scores.rb +122 -0
- data/lib/sportdb/lang.rb +216 -0
- data/lib/sportdb/matcher.rb +31 -0
- data/lib/sportdb/models.rb +259 -0
- data/lib/sportdb/models/assoc.rb +106 -0
- data/lib/sportdb/models/assoc_assoc.rb +15 -0
- data/lib/sportdb/models/badge.rb +14 -0
- data/lib/sportdb/models/event.rb +65 -0
- data/lib/sportdb/models/event_ground.rb +15 -0
- data/lib/sportdb/models/event_team.rb +16 -0
- data/lib/sportdb/models/forward.rb +55 -0
- data/lib/sportdb/models/game.rb +244 -0
- data/lib/sportdb/models/goal.rb +15 -0
- data/lib/sportdb/models/ground.rb +100 -0
- data/lib/sportdb/models/group.rb +23 -0
- data/lib/sportdb/models/group_team.rb +14 -0
- data/lib/sportdb/models/league.rb +83 -0
- data/lib/sportdb/models/person.rb +21 -0
- data/lib/sportdb/models/roster.rb +18 -0
- data/lib/sportdb/models/round.rb +22 -0
- data/lib/sportdb/models/season.rb +14 -0
- data/lib/sportdb/models/stats/alltime_standing.rb +44 -0
- data/lib/sportdb/models/stats/alltime_standing_entry.rb +23 -0
- data/lib/sportdb/models/stats/event_standing.rb +55 -0
- data/lib/sportdb/models/stats/event_standing_entry.rb +21 -0
- data/lib/sportdb/models/stats/group_standing.rb +50 -0
- data/lib/sportdb/models/stats/group_standing_entry.rb +22 -0
- data/lib/sportdb/models/team.rb +119 -0
- data/lib/sportdb/models/team_comp.rb +64 -0
- data/lib/sportdb/models/utils.rb +78 -0
- data/lib/sportdb/models/world/city.rb +21 -0
- data/lib/sportdb/models/world/continent.rb +20 -0
- data/lib/sportdb/models/world/country.rb +19 -0
- data/lib/sportdb/models/world/region.rb +19 -0
- data/lib/sportdb/patterns.rb +38 -0
- data/lib/sportdb/reader.rb +130 -0
- data/lib/sportdb/reader_file.rb +123 -0
- data/lib/sportdb/reader_zip.rb +165 -0
- data/lib/sportdb/readers/assoc.rb +54 -0
- data/lib/sportdb/readers/event.rb +200 -0
- data/lib/sportdb/readers/game.rb +877 -0
- data/lib/sportdb/readers/ground.rb +53 -0
- data/lib/sportdb/readers/league.rb +54 -0
- data/lib/sportdb/readers/season.rb +83 -0
- data/lib/sportdb/readers/squad_club.rb +201 -0
- data/lib/sportdb/readers/squad_national_team.rb +173 -0
- data/lib/sportdb/readers/team.rb +53 -0
- data/lib/sportdb/schema.rb +373 -0
- data/lib/sportdb/standings.rb +178 -0
- data/lib/sportdb/stats.rb +27 -0
- data/lib/sportdb/utils.rb +89 -0
- data/lib/sportdb/utils_date.rb +26 -0
- data/lib/sportdb/utils_goals.rb +20 -0
- data/lib/sportdb/utils_group.rb +63 -0
- data/lib/sportdb/utils_map.rb +44 -0
- data/lib/sportdb/utils_round.rb +165 -0
- data/lib/sportdb/utils_scores.rb +17 -0
- data/lib/sportdb/utils_teams.rb +43 -0
- data/lib/sportdb/version.rb +23 -0
- data/test/data/at-austria/2013_14/bl.txt +227 -0
- data/test/data/at-austria/2013_14/bl.yml +30 -0
- data/test/data/at-austria/2013_14/bl_ii.txt +154 -0
- data/test/data/at-austria/2013_14/el.txt +4 -0
- data/test/data/at-austria/2013_14/el.yml +25 -0
- data/test/data/at-austria/2013_14/squads/austria.txt +40 -0
- data/test/data/at-austria/2013_14/squads/salzburg.txt +35 -0
- data/test/data/at-austria/leagues.txt +11 -0
- data/test/data/at-austria/teams.txt +75 -0
- data/test/data/at-austria/teams_2.txt +34 -0
- data/test/data/national-teams/assocs.txt +231 -0
- data/test/data/national-teams/europe/assocs.txt +13 -0
- data/test/data/national-teams/europe/teams.txt +13 -0
- data/test/data/national-teams/north-america/assocs.txt +10 -0
- data/test/data/national-teams/north-america/teams.txt +7 -0
- data/test/data/national-teams/teams.txt +19 -0
- data/test/data/players/europe/at-austria/players.txt +45 -0
- data/test/data/players/europe/de-deutschland/players.txt +41 -0
- data/test/data/players/south-america/br-brazil/players.txt +51 -0
- data/test/data/world-cup/1930/cup.txt +71 -0
- data/test/data/world-cup/1930/cup.yml +23 -0
- data/test/data/world-cup/1930/cup_goals.txt +47 -0
- data/test/data/world-cup/1930/cup_goals.yml +23 -0
- data/test/data/world-cup/1954/cup.txt +90 -0
- data/test/data/world-cup/1954/cup.yml +30 -0
- data/test/data/world-cup/1962/cup.txt +86 -0
- data/test/data/world-cup/1962/cup.yml +32 -0
- data/test/data/world-cup/1974/cup.yml +35 -0
- data/test/data/world-cup/1974/cup_finals.txt +14 -0
- data/test/data/world-cup/1974/cup_i.txt +55 -0
- data/test/data/world-cup/1974/cup_ii.txt +34 -0
- data/test/data/world-cup/2014/cup.txt +5 -0
- data/test/data/world-cup/2014/cup.yml +54 -0
- data/test/data/world-cup/2014/squads/br-brazil.txt +46 -0
- data/test/data/world-cup/2014/squads/de-deutschland.txt +8 -0
- data/test/data/world-cup/2014/squads/jp-japan.txt +30 -0
- data/test/data/world-cup/2014/squads/uy-uruguay.txt +32 -0
- data/test/data/world-cup/leagues.txt +5 -0
- data/test/data/world-cup/seasons_1930.txt +4 -0
- data/test/data/world-cup/seasons_1954.txt +4 -0
- data/test/data/world-cup/seasons_1962.txt +4 -0
- data/test/data/world-cup/seasons_1974.txt +5 -0
- data/test/data/world-cup/teams_1930.txt +26 -0
- data/test/data/world-cup/teams_1954.txt +30 -0
- data/test/data/world-cup/teams_1962.txt +29 -0
- data/test/data/world-cup/teams_1974.txt +29 -0
- data/test/helper.rb +120 -0
- data/test/test_assoc_reader.rb +201 -0
- data/test/test_changes.rb +74 -0
- data/test/test_cursor.rb +50 -0
- data/test/test_date.rb +100 -0
- data/test/test_goals.rb +109 -0
- data/test/test_lang.rb +130 -0
- data/test/test_load.rb +61 -0
- data/test/test_reader.rb +88 -0
- data/test/test_reader_from_string.rb +65 -0
- data/test/test_round_auto.rb +370 -0
- data/test/test_round_def.rb +109 -0
- data/test/test_round_header.rb +183 -0
- data/test/test_scores.rb +70 -0
- data/test/test_squad_club_reader.rb +76 -0
- data/test/test_squad_national_team_reader.rb +116 -0
- data/test/test_standings.rb +279 -0
- data/test/test_standings_ii.rb +46 -0
- data/test/test_utils.rb +124 -0
- data/test/test_winner.rb +95 -0
- metadata +378 -0
@@ -0,0 +1,106 @@
|
|
1
|
+
module SportDb
|
2
|
+
module Model
|
3
|
+
|
4
|
+
class Assoc < ActiveRecord::Base
|
5
|
+
|
6
|
+
has_many :parent_assoc_assocs, class_name: 'AssocAssoc', foreign_key: 'assoc2_id'
|
7
|
+
## child_assocs - use child_assocs? - (direct) member/child assocs instead of member?
|
8
|
+
has_many :member_assoc_assocs, class_name: 'AssocAssoc', foreign_key: 'assoc1_id'
|
9
|
+
|
10
|
+
|
11
|
+
## note: split member_assocs into two sets (into national=true and national=false)
|
12
|
+
# e.g. fifa has six member confederations (non-national) and 216 national assocs
|
13
|
+
if ActiveRecord::VERSION::MAJOR == 3
|
14
|
+
has_many :all_assocs, class_name: 'Assoc', :source => :assoc2, :through => :member_assoc_assocs
|
15
|
+
has_many :sub_assocs, class_name: 'Assoc', :source => :assoc2, :through => :member_assoc_assocs, conditions: { national: false }
|
16
|
+
has_many :national_assocs, class_name: 'Assoc', :source => :assoc2, :through => :member_assoc_assocs, conditions: { national: true }
|
17
|
+
else
|
18
|
+
## note: includes all member (sub assocs + national assocs) - rename to member_assocs?
|
19
|
+
has_many :all_assocs, class_name: 'Assoc', :source => :assoc2, :through => :member_assoc_assocs
|
20
|
+
## use zone/region as name instead of sub ( for confederatons,zones,etc.)
|
21
|
+
has_many :sub_assocs, -> { where( national: false ) }, class_name: 'Assoc', :source => :assoc2, :through => :member_assoc_assocs
|
22
|
+
has_many :national_assocs, -> { where( national: true ) }, class_name: 'Assoc', :source => :assoc2, :through => :member_assoc_assocs
|
23
|
+
end
|
24
|
+
|
25
|
+
## for now can have more than one (direct) parent assoc
|
26
|
+
## e.g. Africa Fed and Arab League Fed
|
27
|
+
has_many :parent_assocs, class_name: 'Assoc', :source => :assoc1, :through => :parent_assoc_assocs
|
28
|
+
|
29
|
+
# assoc only can have one direct team for now (uses belongs_to on other side)
|
30
|
+
# has_one :team
|
31
|
+
|
32
|
+
|
33
|
+
def self.create_or_update_from_values( new_attributes, values )
|
34
|
+
|
35
|
+
## fix: add/configure logger for ActiveRecord!!!
|
36
|
+
logger = LogUtils::Logger.root
|
37
|
+
|
38
|
+
assoc_keys = [] # by default no association (e.g. fifa,uefa,etc.)
|
39
|
+
|
40
|
+
## check optional values
|
41
|
+
values.each_with_index do |value, index|
|
42
|
+
if value =~ /^(18|19|20)[0-9]{2}$/ ## assume founding year -- allow 18|19|20
|
43
|
+
## logger.info " founding/opening year #{value}"
|
44
|
+
new_attributes[ :since ] = value.to_i
|
45
|
+
elsif value =~ /\/{2}/ # assume it's an address line e.g. xx // xx
|
46
|
+
logger.info " found address line #{value}"
|
47
|
+
## new_attributes[ :address ] = value
|
48
|
+
elsif value =~ /^(?:[a-z]{2}\.)?wikipedia:/ # assume it's wikipedia e.g. [es.]wikipedia:
|
49
|
+
logger.info " found wikipedia line #{value}; skipping for now"
|
50
|
+
elsif value =~ /(^www\.)|(\.com$)/ # FIX: !!!! use a better matcher not just www. and .com
|
51
|
+
new_attributes[ :web ] = value
|
52
|
+
## elsif value =~ /^[a-z]{2}$/ ## assume two-letter country key e.g. at,de,mx,etc.
|
53
|
+
## ## fix: allow country letter with three e.g. eng,sco,wal,nir, etc. !!!
|
54
|
+
## value_country = Country.find_by_key!( value )
|
55
|
+
## new_attributes[ :country_id ] = value_country.id
|
56
|
+
elsif value =~ /^[a-z]{2}$/ ## assume two-letter country key e.g. at,de,mx,etc.
|
57
|
+
## fix: allow country letter with three e.g. eng,sco,wal,nir, etc. !!!
|
58
|
+
## fix: if country does NOT match / NOT found - just coninue w/ next match!!!!
|
59
|
+
# - just issue an error/warn do NOT crash
|
60
|
+
value_country = Country.find_by_key!( value )
|
61
|
+
new_attributes[ :country_id ] = value_country.id
|
62
|
+
## note: if country present - assume it's a national assoc, thus, set flag to true
|
63
|
+
new_attributes[ :national ] = true
|
64
|
+
elsif value =~ /^[a-z|]+$/ ## looks like a tag list e.g. fifa|uefa or fifa|caf or ocf?
|
65
|
+
logger.info " trying adding assocs using keys >#{value}<"
|
66
|
+
assoc_keys = value.split('|')
|
67
|
+
else
|
68
|
+
## todo: assume title2 ??
|
69
|
+
# issue warning: unknown type for value
|
70
|
+
logger.warn "unknown type for value >#{value}< - key #{new_attributes[:key]}"
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
rec = Assoc.find_by_key( new_attributes[ :key ] )
|
75
|
+
if rec.present?
|
76
|
+
logger.debug "update Assoc #{rec.id}-#{rec.key}:"
|
77
|
+
else
|
78
|
+
logger.debug "create Assoc:"
|
79
|
+
rec = Assoc.new
|
80
|
+
end
|
81
|
+
|
82
|
+
logger.debug new_attributes.to_json
|
83
|
+
|
84
|
+
rec.update_attributes!( new_attributes )
|
85
|
+
|
86
|
+
unless assoc_keys.empty?
|
87
|
+
## add team to assocs
|
88
|
+
assoc_keys.each do |assoc_key|
|
89
|
+
assoc = Assoc.find_by_key!( assoc_key )
|
90
|
+
logger.debug " adding assoc to assoc >#{assoc.title}<"
|
91
|
+
|
92
|
+
### todo/fix: how can we delete assoc_assocs? for now only update n create
|
93
|
+
assoc_assoc = AssocAssoc.where( assoc1_id: assoc.id, assoc2_id: rec.id ).first
|
94
|
+
if assoc_assoc.nil? ## create if does NOT exist yet
|
95
|
+
AssocAssoc.create!( assoc1_id: assoc.id, assoc2_id: rec.id )
|
96
|
+
end
|
97
|
+
end
|
98
|
+
end
|
99
|
+
|
100
|
+
end # create_or_update_from_values
|
101
|
+
|
102
|
+
end # class Assoc
|
103
|
+
|
104
|
+
|
105
|
+
end # module Model
|
106
|
+
end # module SportDb
|
@@ -0,0 +1,15 @@
|
|
1
|
+
module SportDb
|
2
|
+
module Model
|
3
|
+
|
4
|
+
|
5
|
+
class AssocAssoc < ActiveRecord::Base
|
6
|
+
self.table_name = 'assocs_assocs'
|
7
|
+
|
8
|
+
belongs_to :assoc1, class_name: 'Assoc', foreign_key: 'assoc1_id' # parent assoc
|
9
|
+
belongs_to :assoc2, class_name: 'Assoc', foreign_key: 'assoc2_id' # child assoc is_member_of parent assoc
|
10
|
+
|
11
|
+
end # class AssocAssoc
|
12
|
+
|
13
|
+
|
14
|
+
end # module Model
|
15
|
+
end # module SportDb
|
@@ -0,0 +1,65 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
module SportDb
|
4
|
+
module Model
|
5
|
+
|
6
|
+
class Event < ActiveRecord::Base
|
7
|
+
|
8
|
+
belongs_to :league
|
9
|
+
belongs_to :season
|
10
|
+
|
11
|
+
if ActiveRecord::VERSION::MAJOR == 3
|
12
|
+
has_many :rounds, order: 'pos' # all (fix and flex) rounds
|
13
|
+
has_many :groups, order: 'pos'
|
14
|
+
else
|
15
|
+
has_many :rounds, -> { order('pos') } # all (fix and flex) rounds
|
16
|
+
has_many :groups, -> { order('pos') }
|
17
|
+
end
|
18
|
+
|
19
|
+
has_many :games, :through => :rounds
|
20
|
+
|
21
|
+
has_many :event_teams, class_name: 'EventTeam'
|
22
|
+
has_many :teams, :through => :event_teams
|
23
|
+
|
24
|
+
has_many :event_grounds, class_name: 'EventGround'
|
25
|
+
has_many :grounds, :through => :event_grounds
|
26
|
+
|
27
|
+
|
28
|
+
before_save :on_before_save
|
29
|
+
|
30
|
+
|
31
|
+
def add_teams_from_ary!( team_keys )
|
32
|
+
## move to depreciated? used in event reader? why? why not?
|
33
|
+
team_keys.each do |team_key|
|
34
|
+
team = Team.find_by_key!( team_key )
|
35
|
+
self.teams << team
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
def on_before_save
|
40
|
+
# event key is composite of league + season (e.g. at.2012/13) etc.
|
41
|
+
self.key = "#{league.key}.#{season.key}"
|
42
|
+
end
|
43
|
+
|
44
|
+
def title
|
45
|
+
"#{league.title} #{season.title}"
|
46
|
+
end
|
47
|
+
|
48
|
+
|
49
|
+
#####################
|
50
|
+
## convenience helper for text parser/reader
|
51
|
+
|
52
|
+
###
|
53
|
+
## fix: use/add to_teams_table( rec ) for reuse
|
54
|
+
#
|
55
|
+
## @known_teams = @event.known_teams_table
|
56
|
+
|
57
|
+
|
58
|
+
def known_teams_table
|
59
|
+
@known_teams_table ||= TextUtils.build_title_table_for( teams )
|
60
|
+
end # method known_teams_table
|
61
|
+
|
62
|
+
end # class Event
|
63
|
+
|
64
|
+
end # module Model
|
65
|
+
end # module SportDb
|
@@ -0,0 +1,55 @@
|
|
1
|
+
|
2
|
+
### forward references
|
3
|
+
## require first to resolve circular references
|
4
|
+
|
5
|
+
module SportDb
|
6
|
+
module Model
|
7
|
+
|
8
|
+
Prop = ConfDb::Model::Prop
|
9
|
+
|
10
|
+
## todo: why? why not use include WorldDb::Models here???
|
11
|
+
Continent = WorldDb::Model::Continent
|
12
|
+
Country = WorldDb::Model::Country
|
13
|
+
Region = WorldDb::Model::Region
|
14
|
+
City = WorldDb::Model::City
|
15
|
+
|
16
|
+
Person = PersonDb::Model::Person
|
17
|
+
|
18
|
+
## nb: for now only team and league use worlddb tables
|
19
|
+
# e.g. with belongs_to assoc (country,region)
|
20
|
+
|
21
|
+
class Assoc < ActiveRecord::Base ; end
|
22
|
+
class Team < ActiveRecord::Base ; end
|
23
|
+
class League < ActiveRecord::Base ; end
|
24
|
+
class Ground < ActiveRecord::Base ; end
|
25
|
+
class Goal < ActiveRecord::Base ; end
|
26
|
+
|
27
|
+
end
|
28
|
+
|
29
|
+
## add backwards compatible n convenience namespace
|
30
|
+
Models = Model
|
31
|
+
end # module SportDb
|
32
|
+
|
33
|
+
|
34
|
+
module WorldDb
|
35
|
+
module Model
|
36
|
+
|
37
|
+
# add alias? why? why not? # is there a better way?
|
38
|
+
# - just include SportDb::Models - why? why not?
|
39
|
+
# - just include once in loader??
|
40
|
+
Assoc = SportDb::Model::Assoc
|
41
|
+
Team = SportDb::Model::Team
|
42
|
+
League = SportDb::Model::League
|
43
|
+
Ground = SportDb::Model::Ground
|
44
|
+
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
|
49
|
+
module PersonDb
|
50
|
+
module Model
|
51
|
+
Goal = SportDb::Model::Goal
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
|
@@ -0,0 +1,244 @@
|
|
1
|
+
|
2
|
+
module SportDb
|
3
|
+
module Model
|
4
|
+
|
5
|
+
|
6
|
+
class Game < ActiveRecord::Base
|
7
|
+
|
8
|
+
belongs_to :team1, class_name: 'Team', foreign_key: 'team1_id'
|
9
|
+
belongs_to :team2, class_name: 'Team', foreign_key: 'team2_id'
|
10
|
+
|
11
|
+
belongs_to :round
|
12
|
+
belongs_to :group # group is optional
|
13
|
+
|
14
|
+
belongs_to :ground # ground is optional
|
15
|
+
belongs_to :city, class_name: 'WorldDb::Model::City', foreign_key: 'city_id' # city is optioanl (remove?? redundant?? use ground ??)
|
16
|
+
|
17
|
+
has_many :goals, :dependent => :delete_all
|
18
|
+
|
19
|
+
|
20
|
+
before_save :calc_winner
|
21
|
+
|
22
|
+
|
23
|
+
def team1_name() team1.name; end
|
24
|
+
def team2_name() team2.name; end
|
25
|
+
|
26
|
+
|
27
|
+
def toto12x() toto1x2; end # alias for toto12x - todo/fix: use ruby alias helper
|
28
|
+
def toto1x2
|
29
|
+
## note: will return string e.g. 1-X-2 (winner will return int e.g. 1-0-2)
|
30
|
+
|
31
|
+
## fix: use switch/when expr/stmt instead of ifs
|
32
|
+
value = winner90 # 1 0 2 1 => team 1 0 => draw 2 => team
|
33
|
+
if value == 0
|
34
|
+
'X'
|
35
|
+
elsif value == 1
|
36
|
+
'1'
|
37
|
+
elsif value == 2
|
38
|
+
'2'
|
39
|
+
elsif value == -1
|
40
|
+
nil # ??? - unknown -- include --??? why? why not??
|
41
|
+
else
|
42
|
+
nil
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
|
47
|
+
def winner1?() winner == 1; end
|
48
|
+
def winner2?() winner == 2; end
|
49
|
+
def draw? () winner == 0; end # use different name; use an alias (any better names more speaking???)
|
50
|
+
|
51
|
+
|
52
|
+
|
53
|
+
## winner after extra time (will ignore possible penalty shootout; used for alltime standings in world cup calc, for example)
|
54
|
+
## - also add winnerp nil,1,2 => nil -> no penalty shoutout (or no scores) -- needed for what?
|
55
|
+
def winneret
|
56
|
+
## check for extra time
|
57
|
+
if score1et.present? && score2et.present?
|
58
|
+
if score1et > score2et
|
59
|
+
1
|
60
|
+
elsif score1et < score2et
|
61
|
+
2
|
62
|
+
else # assume score1et == score2et - draw
|
63
|
+
0
|
64
|
+
end
|
65
|
+
else
|
66
|
+
nil # no extra time; note: return nil use winneret || winner90 to get result for both extra time or if not present regular time
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
|
71
|
+
def calc_winner
|
72
|
+
if score1.nil? || score2.nil?
|
73
|
+
self.winner90 = nil
|
74
|
+
self.winner = nil
|
75
|
+
else
|
76
|
+
if score1 > score2
|
77
|
+
self.winner90 = 1
|
78
|
+
elsif score1 < score2
|
79
|
+
self.winner90 = 2
|
80
|
+
else # assume score1 == score2 - draw
|
81
|
+
self.winner90 = 0
|
82
|
+
end
|
83
|
+
|
84
|
+
## todo/fix:
|
85
|
+
# check for next-game/pre-game !!!
|
86
|
+
# use 1st leg and 2nd leg - use for winner too
|
87
|
+
# or add new winner_total or winner_aggregated method ???
|
88
|
+
|
89
|
+
## check for penalty - note: some games might only have penalty and no extra time (e.g. copa liberatadores)
|
90
|
+
if score1p.present? && score2p.present?
|
91
|
+
if score1p > score2p
|
92
|
+
self.winner = 1
|
93
|
+
elsif score1p < score2p
|
94
|
+
self.winner = 2
|
95
|
+
else
|
96
|
+
# issue warning! - should not happen; penalty goes on until winner found!
|
97
|
+
puts "*** warn: should not happen; penalty goes on until winner found"
|
98
|
+
end
|
99
|
+
## check for extra time
|
100
|
+
elsif score1et.present? && score2et.present?
|
101
|
+
if score1et > score2et
|
102
|
+
self.winner = 1
|
103
|
+
elsif score1et < score2et
|
104
|
+
self.winner = 2
|
105
|
+
else # assume score1et == score2et - draw
|
106
|
+
self.winner = 0
|
107
|
+
end
|
108
|
+
else
|
109
|
+
# assume no penalty and no extra time; same as 90min result
|
110
|
+
self.winner = self.winner90
|
111
|
+
end
|
112
|
+
end
|
113
|
+
end
|
114
|
+
|
115
|
+
|
116
|
+
### getter/setters for deprecated attribs (score3,4,5,6) n national
|
117
|
+
|
118
|
+
def score1ot() score1et end
|
119
|
+
def score2ot() score2et end
|
120
|
+
|
121
|
+
def score1ot=(value) self.score1et = value end
|
122
|
+
def score2ot=(value) self.score2et = value end
|
123
|
+
|
124
|
+
|
125
|
+
# game over?
|
126
|
+
def over?() play_at <= Time.now; end
|
127
|
+
|
128
|
+
## fix/todo: already added by ar magic ??? remove code
|
129
|
+
def knockout?() knockout == true; end
|
130
|
+
def complete?() score1.present? && score2.present?; end
|
131
|
+
|
132
|
+
|
133
|
+
############# convenience helpers for styling
|
134
|
+
##
|
135
|
+
|
136
|
+
def team1_style_class
|
137
|
+
buf = ''
|
138
|
+
## NB: remove if calc?
|
139
|
+
|
140
|
+
### fix: loser
|
141
|
+
## - add method for checking winner/loser on ko pairs using (1st leg/2nd leg totals) ??
|
142
|
+
## use new winner_total method ??
|
143
|
+
|
144
|
+
if complete?
|
145
|
+
if winner1?
|
146
|
+
buf << 'game-team-winner '
|
147
|
+
elsif winner2?
|
148
|
+
buf << 'game-team-loser '
|
149
|
+
else # assume draw
|
150
|
+
buf << 'game-team-draw '
|
151
|
+
end
|
152
|
+
end
|
153
|
+
|
154
|
+
buf << 'game-knockout ' if knockout?
|
155
|
+
buf
|
156
|
+
end
|
157
|
+
|
158
|
+
def team2_style_class
|
159
|
+
buf = ''
|
160
|
+
## NB: remove if calc?
|
161
|
+
|
162
|
+
### fix: loser
|
163
|
+
## - add method for checking winner/loser on ko pairs using (1st leg/2nd leg totals) ??
|
164
|
+
## use new winner_total method ??
|
165
|
+
|
166
|
+
if complete?
|
167
|
+
if winner1?
|
168
|
+
buf << 'game-team-loser '
|
169
|
+
elsif winner2?
|
170
|
+
buf << 'game-team-winner '
|
171
|
+
else # assume draw
|
172
|
+
buf << 'game-team-draw '
|
173
|
+
end
|
174
|
+
end
|
175
|
+
|
176
|
+
buf << 'game-knockout ' if knockout?
|
177
|
+
buf
|
178
|
+
end
|
179
|
+
|
180
|
+
|
181
|
+
def play_at_str( format = nil )
|
182
|
+
## e.g. use like
|
183
|
+
# play_at_str or
|
184
|
+
# play_at_str( :db ) etc.
|
185
|
+
if format == :db
|
186
|
+
play_at.strftime( '%Y-%m-%d %H:%M %z' ) # NB: removed seconds (:%S)
|
187
|
+
else
|
188
|
+
play_at.strftime( "%a. %d. %b. / %H:%M" )
|
189
|
+
end
|
190
|
+
end
|
191
|
+
|
192
|
+
|
193
|
+
def score_str
|
194
|
+
## return ' - ' if score1.nil? && score2.nil?
|
195
|
+
|
196
|
+
# note: make after extra time optional;
|
197
|
+
# e.g. copa liberatadores only has regular time plus penalty, for example
|
198
|
+
|
199
|
+
buf = ""
|
200
|
+
|
201
|
+
buf << "#{score1_str} : #{score2_str}"
|
202
|
+
buf << " / #{score1et_str} : #{score2et_str} n.V." if score1et.present? || score2et.present?
|
203
|
+
buf << " / #{score1p_str} : #{score2p_str} i.E." if score1p.present? || score2p.present?
|
204
|
+
|
205
|
+
buf
|
206
|
+
end
|
207
|
+
|
208
|
+
def score1_str() score1.nil? ? '-' : score1.to_s; end
|
209
|
+
def score2_str() score2.nil? ? '-' : score2.to_s; end
|
210
|
+
|
211
|
+
def score1et_str() score1et.nil? ? '-' : score1et.to_s; end
|
212
|
+
def score2et_str() score2et.nil? ? '-' : score2et.to_s; end
|
213
|
+
|
214
|
+
def score1p_str() score1p.nil? ? '-' : score1p.to_s; end
|
215
|
+
def score2p_str() score2p.nil? ? '-' : score2p.to_s; end
|
216
|
+
|
217
|
+
|
218
|
+
|
219
|
+
## todo/fix: find a better name?
|
220
|
+
## todo: move to utils for reuse?
|
221
|
+
|
222
|
+
def check_for_changes( new_attributes )
|
223
|
+
changes_counter = 0
|
224
|
+
new_attributes.each do |key,new_value|
|
225
|
+
old_value = attributes[ key.to_s ]
|
226
|
+
## todo/fix: also check for class/type matching ????
|
227
|
+
if new_value == old_value
|
228
|
+
# do nothing
|
229
|
+
else
|
230
|
+
changes_counter +=1
|
231
|
+
puts "change #{changes_counter} for #{key} old:>#{old_value}< : #{old_value.class.name} new:>#{new_value}< : #{new_value.class.name}"
|
232
|
+
end
|
233
|
+
end
|
234
|
+
|
235
|
+
# no changes found for counter==0;
|
236
|
+
# -- otherwise x changes found; return true
|
237
|
+
changes_counter == 0 ? false : true
|
238
|
+
end
|
239
|
+
|
240
|
+
end # class Game
|
241
|
+
|
242
|
+
|
243
|
+
end # module Model
|
244
|
+
end # module SportDb
|