sportdb 1.8.28 → 1.8.29

Sign up to get free protection for your applications and to get access to all the features.
@@ -24,15 +24,20 @@ lib/sportdb/finders/date.rb
24
24
  lib/sportdb/finders/scores.rb
25
25
  lib/sportdb/lang.rb
26
26
  lib/sportdb/matcher.rb
27
+ lib/sportdb/models/assoc.rb
28
+ lib/sportdb/models/assoc_assoc.rb
27
29
  lib/sportdb/models/badge.rb
28
30
  lib/sportdb/models/event.rb
31
+ lib/sportdb/models/event_comp.rb
29
32
  lib/sportdb/models/event_ground.rb
30
33
  lib/sportdb/models/event_team.rb
31
34
  lib/sportdb/models/forward.rb
32
35
  lib/sportdb/models/game.rb
36
+ lib/sportdb/models/game_comp.rb
33
37
  lib/sportdb/models/goal.rb
34
38
  lib/sportdb/models/ground.rb
35
39
  lib/sportdb/models/group.rb
40
+ lib/sportdb/models/group_comp.rb
36
41
  lib/sportdb/models/group_team.rb
37
42
  lib/sportdb/models/league.rb
38
43
  lib/sportdb/models/person.rb
@@ -49,6 +54,7 @@ lib/sportdb/models/stats/event_standing_entry.rb
49
54
  lib/sportdb/models/stats/group_standing.rb
50
55
  lib/sportdb/models/stats/group_standing_entry.rb
51
56
  lib/sportdb/models/team.rb
57
+ lib/sportdb/models/team_comp.rb
52
58
  lib/sportdb/models/track.rb
53
59
  lib/sportdb/models/utils.rb
54
60
  lib/sportdb/models/world/city.rb
@@ -57,6 +63,7 @@ lib/sportdb/models/world/country.rb
57
63
  lib/sportdb/models/world/region.rb
58
64
  lib/sportdb/patterns.rb
59
65
  lib/sportdb/reader.rb
66
+ lib/sportdb/readers/assoc.rb
60
67
  lib/sportdb/readers/event.rb
61
68
  lib/sportdb/readers/game.rb
62
69
  lib/sportdb/readers/ground.rb
@@ -97,6 +104,12 @@ test/data/at-austria/2013_14/el.yml
97
104
  test/data/at-austria/leagues.txt
98
105
  test/data/at-austria/teams.txt
99
106
  test/data/at-austria/teams_2.txt
107
+ test/data/national-teams/assocs.txt
108
+ test/data/national-teams/europe/assocs.txt
109
+ test/data/national-teams/europe/teams.txt
110
+ test/data/national-teams/north-america/assocs.txt
111
+ test/data/national-teams/north-america/teams.txt
112
+ test/data/national-teams/teams.txt
100
113
  test/data/players/europe/de-deutschland/players.txt
101
114
  test/data/players/south-america/br-brazil/players.txt
102
115
  test/data/world-cup/1930/cup.txt
@@ -123,6 +136,7 @@ test/data/world-cup/teams_1954.txt
123
136
  test/data/world-cup/teams_1962.txt
124
137
  test/data/world-cup/teams_1974.txt
125
138
  test/helper.rb
139
+ test/test_assoc_reader.rb
126
140
  test/test_changes.rb
127
141
  test/test_cursor.rb
128
142
  test/test_date.rb
data/README.md CHANGED
@@ -5,8 +5,8 @@
5
5
  [![Build Status](https://secure.travis-ci.org/geraldb/sport.db.ruby.png?branch=master)](http://travis-ci.org/geraldb/sport.db.ruby)
6
6
  -->
7
7
 
8
- * home :: [github.com/geraldb/sport.db.ruby](https://github.com/geraldb/sport.db.ruby)
9
- * bugs :: [github.com/geraldb/sport.db.ruby/issues](https://github.com/geraldb/sport.db.ruby/issues)
8
+ * home :: [github.com/sportdb/sport.db.ruby](https://github.com/sportdb/sport.db.ruby)
9
+ * bugs :: [github.com/sportdb/sport.db.ruby/issues](https://github.com/sportdb/sport.db.ruby/issues)
10
10
  * gem :: [rubygems.org/gems/sportdb](https://rubygems.org/gems/sportdb)
11
11
  * rdoc :: [rubydoc.info/gems/sportdb](http://rubydoc.info/gems/sportdb)
12
12
  * forum :: [groups.google.com/group/opensport](https://groups.google.com/group/opensport)
data/Rakefile CHANGED
@@ -12,7 +12,7 @@ Hoe.spec 'sportdb' do
12
12
  self.summary = 'sportdb - sport.db command line tool'
13
13
  self.description = summary
14
14
 
15
- self.urls = ['https://github.com/geraldb/sport.db.ruby']
15
+ self.urls = ['https://github.com/sportdb/sport.db.ruby']
16
16
 
17
17
  self.author = 'Gerald Bauer'
18
18
  self.email = 'opensport@googlegroups.com'
@@ -33,14 +33,19 @@ require 'sportdb/models/world/city'
33
33
  require 'sportdb/models/world/country'
34
34
  require 'sportdb/models/world/continent'
35
35
  require 'sportdb/models/world/region'
36
+ require 'sportdb/models/assoc'
37
+ require 'sportdb/models/assoc_assoc'
36
38
  require 'sportdb/models/badge'
37
39
  require 'sportdb/models/event'
40
+ require 'sportdb/models/event_comp'
38
41
  require 'sportdb/models/event_ground'
39
42
  require 'sportdb/models/event_team'
40
43
  require 'sportdb/models/game'
44
+ require 'sportdb/models/game_comp'
41
45
  require 'sportdb/models/goal'
42
46
  require 'sportdb/models/ground'
43
47
  require 'sportdb/models/group'
48
+ require 'sportdb/models/group_comp'
44
49
  require 'sportdb/models/group_team'
45
50
  require 'sportdb/models/league'
46
51
  require 'sportdb/models/person'
@@ -51,6 +56,7 @@ require 'sportdb/models/round'
51
56
  require 'sportdb/models/run'
52
57
  require 'sportdb/models/season'
53
58
  require 'sportdb/models/team'
59
+ require 'sportdb/models/team_comp'
54
60
  require 'sportdb/models/track'
55
61
 
56
62
  require 'sportdb/models/stats/alltime_standing'
@@ -86,6 +92,7 @@ require 'sportdb/matcher'
86
92
  require 'sportdb/calc'
87
93
 
88
94
 
95
+ require 'sportdb/readers/assoc'
89
96
  require 'sportdb/readers/event'
90
97
  require 'sportdb/readers/game'
91
98
  require 'sportdb/readers/ground'
@@ -40,6 +40,9 @@ module SportDb
40
40
  Season.delete_all
41
41
 
42
42
  Ground.delete_all # stadiums
43
+
44
+ Assoc.delete_all # associations / organizations
45
+ AssocAssoc.delete_all # associations / organizations
43
46
  end
44
47
 
45
48
  end # class Deleter
@@ -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
@@ -9,8 +9,8 @@ class Event < ActiveRecord::Base
9
9
  belongs_to :season
10
10
 
11
11
  if ActiveRecord::VERSION::MAJOR == 3
12
- has_many :rounds, :order => 'pos' # all (fix and flex) rounds
13
- has_many :groups, :order => 'pos'
12
+ has_many :rounds, order: 'pos' # all (fix and flex) rounds
13
+ has_many :groups, order: 'pos'
14
14
  else
15
15
  has_many :rounds, -> { order('pos') } # all (fix and flex) rounds
16
16
  has_many :groups, -> { order('pos') }
@@ -18,16 +18,18 @@ end
18
18
 
19
19
  has_many :games, :through => :rounds
20
20
 
21
- has_many :event_teams, :class_name => 'EventTeam'
21
+ has_many :event_teams, class_name: 'EventTeam'
22
22
  has_many :teams, :through => :event_teams
23
23
 
24
- has_many :event_grounds, :class_name => 'EventGround'
24
+ has_many :event_grounds, class_name: 'EventGround'
25
25
  has_many :grounds, :through => :event_grounds
26
26
 
27
27
 
28
28
  before_save :on_before_save
29
29
 
30
+
30
31
  def add_teams_from_ary!( team_keys )
32
+ ## move to depreciated? used in event reader? why? why not?
31
33
  team_keys.each do |team_key|
32
34
  team = Team.find_by_key!( team_key )
33
35
  self.teams << team
@@ -43,11 +45,6 @@ end
43
45
  "#{league.title} #{season.title}"
44
46
  end
45
47
 
46
- def full_title # includes season (e.g. year)
47
- puts "*** depreciated API call Event#full_title; use Event#title instead; full_title will get removed"
48
- "#{league.title} #{season.title}"
49
- end
50
-
51
48
 
52
49
  #####################
53
50
  ## convenience helper for text parser/reader
@@ -0,0 +1,21 @@
1
+ # encoding: utf-8
2
+
3
+ module SportDb
4
+ module Model
5
+
6
+ #############################################################
7
+ # collect depreciated or methods for future removal here
8
+ # - keep for now for compatibility (for old code)
9
+
10
+ class Event
11
+
12
+ def full_title # includes season (e.g. year)
13
+ puts "*** depreciated API call Event#full_title; use Event#title instead; full_title will get removed"
14
+ "#{league.title} #{season.title}"
15
+ end
16
+
17
+ end # class Event
18
+
19
+
20
+ end # module Model
21
+ end # module SportDb
@@ -18,6 +18,7 @@ module SportDb
18
18
  ## nb: for now only team and league use worlddb tables
19
19
  # e.g. with belongs_to assoc (country,region)
20
20
 
21
+ class Assoc < ActiveRecord::Base ; end
21
22
  class Team < ActiveRecord::Base ; end
22
23
  class League < ActiveRecord::Base ; end
23
24
  class Ground < ActiveRecord::Base ; end
@@ -33,6 +34,7 @@ module WorldDb
33
34
  # add alias? why? why not? # is there a better way?
34
35
  # - just include SportDb::Models - why? why not?
35
36
  # - just include once in loader??
37
+ Assoc = SportDb::Model::Assoc
36
38
  Team = SportDb::Model::Team
37
39
  League = SportDb::Model::League
38
40
  Ground = SportDb::Model::Ground
@@ -92,165 +92,18 @@ class Game < ActiveRecord::Base
92
92
 
93
93
  ### getter/setters for deprecated attribs (score3,4,5,6) n national
94
94
 
95
- def score3() score1et end
96
- def score4() score2et end
97
95
  def score1ot() score1et end
98
96
  def score2ot() score2et end
99
- def score5() score1p end
100
- def score6() score2p end
101
97
 
102
- def score3=(value) self.score1et = value end
103
- def score4=(value) self.score2et = value end
104
98
  def score1ot=(value) self.score1et = value end
105
99
  def score2ot=(value) self.score2et = value end
106
- def score5=(value) self.score1p = value end
107
- def score6=(value) self.score2p = value end
108
100
 
109
101
 
110
-
111
- def self.create_knockouts_from_ary!( games, round )
112
- Game.create_from_ary!( games, round, true )
113
- end
114
-
115
- def self.create_from_ary!( games, round, knockout=false )
116
-
117
- ### fix:
118
- # replace knockout=false with more attribs
119
- # see create teams and than merge attribs
120
-
121
- games.each_with_index do |values,index|
122
-
123
- value_pos = index+1
124
- value_scores = []
125
- value_teams = []
126
- value_knockout = knockout
127
- value_play_at = round.start_at # if no date present use it from round
128
- value_group = nil
129
-
130
- ### lets you use arguments in any order
131
- ## makes pos optional (if not present counting from 1 to n)
132
-
133
- values.each do |value|
134
- if value.kind_of? Numeric
135
- value_pos = value
136
- elsif value.kind_of?( TrueClass ) || value.kind_of?( FalseClass )
137
- value_knockout = value
138
- elsif value.kind_of? Array
139
- value_scores = value
140
- elsif value.kind_of? Team
141
- value_teams << value
142
- elsif value.kind_of? Group
143
- value_group = value
144
- elsif value.kind_of?( Date ) || value.kind_of?( Time ) || value.kind_of?( DateTime )
145
- value_play_at = value
146
- else
147
- # issue an error/warning here
148
- end
149
- end
150
-
151
- Game.create!(
152
- :round => round,
153
- :pos => value_pos,
154
- :team1 => value_teams[0],
155
- :score1 => value_scores[0],
156
- :score2 => value_scores[1],
157
- :score1et => value_scores[2],
158
- :score2et => value_scores[3],
159
- :score1p => value_scores[4],
160
- :score2p => value_scores[5],
161
- :team2 => value_teams[1],
162
- :play_at => value_play_at,
163
- :group => value_group, # Note: group is optional (may be null/nil)
164
- :knockout => value_knockout )
165
- end # each games
166
- end
167
-
168
- def self.create_pairs_from_ary_for_group!( pairs, group )
169
-
170
- pairs.each do |pair|
171
- game1_attribs = {
172
- :round =>pair[0][5],
173
- :pos =>pair[0][0],
174
- :team1 =>pair[0][1],
175
- :score1 =>pair[0][2][0],
176
- :score2 =>pair[0][2][1],
177
- :team2 =>pair[0][3],
178
- :play_at =>pair[0][4],
179
- :group =>group }
180
-
181
- game2_attribs = {
182
- :round =>pair[1][5],
183
- :pos =>pair[1][0],
184
- :team1 =>pair[1][1],
185
- :score1 =>pair[1][2][0],
186
- :score2 =>pair[1][2][1],
187
- :team2 =>pair[1][3],
188
- :play_at =>pair[1][4],
189
- :group =>group }
190
-
191
- game1 = Game.create!( game1_attribs )
192
- game2 = Game.create!( game2_attribs )
193
-
194
- # linkup games
195
- game1.next_game_id = game2.id
196
- game1.save!
197
-
198
- game2.prev_game_id = game1.id
199
- game2.save!
200
- end # each pair
201
- end
202
-
203
- def self.create_knockout_pairs_from_ary!( pairs, round1, round2 )
204
-
205
- pairs.each do |pair|
206
- game1_attribs = {
207
- :round =>round1,
208
- :pos =>pair[0][0],
209
- :team1 =>pair[0][1],
210
- :score1 =>pair[0][2][0],
211
- :score2 =>pair[0][2][1],
212
- :team2 =>pair[0][3],
213
- :play_at =>pair[0][4] }
214
-
215
- game2_attribs = {
216
- :round =>round2,
217
- :pos =>pair[1][0],
218
- :team1 =>pair[1][1],
219
- :score1 =>pair[1][2][0],
220
- :score2 =>pair[1][2][1],
221
- :score1et =>pair[1][2][2],
222
- :score2et =>pair[1][2][3],
223
- :score1p =>pair[1][2][4],
224
- :score1p =>pair[1][2][5],
225
- :team2 =>pair[1][3],
226
- :play_at =>pair[1][4],
227
- :knockout =>true }
228
-
229
- game1 = Game.create!( game1_attribs )
230
- game2 = Game.create!( game2_attribs )
231
-
232
- # linkup games
233
- game1.next_game_id = game2.id
234
- game1.save!
235
-
236
- game2.prev_game_id = game1.id
237
- game2.save!
238
- end # each pair
239
- end
240
-
241
-
242
- def over? # game over?
243
- play_at <= Time.now
244
- end
245
-
102
+ # game over?
103
+ def over?() play_at <= Time.now; end
246
104
  ## fix/todo: already added by ar magic ??? remove code
247
- def knockout?
248
- knockout == true
249
- end
250
-
251
- def complete?
252
- score1.present? && score2.present?
253
- end
105
+ def knockout?() knockout == true; end
106
+ def complete?() score1.present? && score2.present?; end
254
107
 
255
108
 
256
109
  ############# convenience helpers for styling