sportdb-formats 1.1.0 → 1.1.5

Sign up to get free protection for your applications and to get access to all the features.
Files changed (56) hide show
  1. checksums.yaml +4 -4
  2. data/Manifest.txt +6 -34
  3. data/Rakefile +3 -6
  4. data/lib/sportdb/formats.rb +54 -70
  5. data/lib/sportdb/formats/country/country_index.rb +2 -2
  6. data/lib/sportdb/formats/event/event_index.rb +141 -0
  7. data/lib/sportdb/formats/event/event_reader.rb +183 -0
  8. data/lib/sportdb/formats/league/league_index.rb +22 -18
  9. data/lib/sportdb/formats/league/league_outline_reader.rb +24 -7
  10. data/lib/sportdb/formats/league/league_reader.rb +7 -1
  11. data/lib/sportdb/formats/match/match_parser.rb +47 -18
  12. data/lib/sportdb/formats/package.rb +59 -11
  13. data/lib/sportdb/formats/team/club_index.rb +13 -11
  14. data/lib/sportdb/formats/team/club_index_history.rb +134 -0
  15. data/lib/sportdb/formats/team/club_reader_history.rb +203 -0
  16. data/lib/sportdb/formats/team/club_reader_props.rb +20 -5
  17. data/lib/sportdb/formats/version.rb +1 -1
  18. data/test/helper.rb +50 -81
  19. data/test/test_club_index_history.rb +107 -0
  20. data/test/test_club_reader_history.rb +212 -0
  21. data/test/test_datafile_package.rb +1 -1
  22. metadata +11 -81
  23. data/lib/sportdb/formats/config.rb +0 -40
  24. data/lib/sportdb/formats/match/match_parser_csv.rb +0 -321
  25. data/lib/sportdb/formats/name_helper.rb +0 -84
  26. data/lib/sportdb/formats/score/score_formats.rb +0 -220
  27. data/lib/sportdb/formats/score/score_parser.rb +0 -202
  28. data/lib/sportdb/formats/season_utils.rb +0 -27
  29. data/lib/sportdb/formats/structs/country.rb +0 -31
  30. data/lib/sportdb/formats/structs/group.rb +0 -18
  31. data/lib/sportdb/formats/structs/league.rb +0 -37
  32. data/lib/sportdb/formats/structs/match.rb +0 -151
  33. data/lib/sportdb/formats/structs/matchlist.rb +0 -220
  34. data/lib/sportdb/formats/structs/round.rb +0 -25
  35. data/lib/sportdb/formats/structs/season.rb +0 -123
  36. data/lib/sportdb/formats/structs/standings.rb +0 -268
  37. data/lib/sportdb/formats/structs/team.rb +0 -150
  38. data/lib/sportdb/formats/structs/team_usage.rb +0 -88
  39. data/test/test_clubs.rb +0 -40
  40. data/test/test_conf.rb +0 -65
  41. data/test/test_csv_match_parser.rb +0 -114
  42. data/test/test_csv_match_parser_utils.rb +0 -20
  43. data/test/test_csv_reader.rb +0 -31
  44. data/test/test_match.rb +0 -30
  45. data/test/test_match_auto.rb +0 -72
  46. data/test/test_match_auto_champs.rb +0 -45
  47. data/test/test_match_auto_euro.rb +0 -37
  48. data/test/test_match_auto_relegation.rb +0 -41
  49. data/test/test_match_auto_worldcup.rb +0 -61
  50. data/test/test_match_champs.rb +0 -27
  51. data/test/test_match_eng.rb +0 -26
  52. data/test/test_match_euro.rb +0 -27
  53. data/test/test_match_worldcup.rb +0 -27
  54. data/test/test_name_helper.rb +0 -67
  55. data/test/test_scores.rb +0 -122
  56. data/test/test_season.rb +0 -62
@@ -1,27 +0,0 @@
1
- # encoding: utf-8
2
-
3
-
4
- module SeasonHelper ## use Helpers why? why not?
5
-
6
- ##############################################
7
- ### deprecated!!! use new Season class!!!
8
- ## this code will get removed!!!!
9
- ###################################################
10
-
11
- def prev( str ) SportDb::Import::Season.new( str ).prev; end
12
- def key( str ) SportDb::Import::Season.new( str ).key; end
13
- def directory( str, format: nil ) SportDb::Import::Season.new( str ).directory( format: format ); end
14
-
15
- ## note: new start_year now returns an integer number (no longer a string)!!!
16
- def start_year( str ) SportDb::Import::Season.new( str ).start_year; end
17
- ## note: new end_year now returns an integer number (no longer a string)!!!
18
- ## if now end_year (year? == true) than returns nil (no longer the start_year "as fallback")!!!
19
- def end_year( str ) SportDb::Import::Season.new( str ).end_year; end
20
- end # module SeasonHelper
21
-
22
-
23
- module SeasonUtils
24
- extend SeasonHelper
25
- ## lets you use SeasonHelper as "globals" eg.
26
- ## SeasonUtils.prev( season ) etc.
27
- end # SeasonUtils
@@ -1,31 +0,0 @@
1
- # encoding: utf-8
2
-
3
- module SportDb
4
- module Import
5
-
6
- ##
7
- # note: check that shape/structure/fields/attributes match
8
- # the ActiveRecord model !!!!
9
-
10
- class Country
11
-
12
- ## note: is read-only/immutable for now - why? why not?
13
- ## add cities (array/list) - why? why not?
14
- attr_reader :key, :name, :code, :tags
15
- attr_accessor :alt_names
16
-
17
- def initialize( key: nil, name:, code:, tags: [] )
18
- ## note: auto-generate key "on-the-fly" if missing for now - why? why not?
19
- ## note: quick hack - auto-generate key, that is, remove all non-ascii chars and downcase
20
- @key = key || name.downcase.gsub( /[^a-z]/, '' )
21
- @name, @code = name, code
22
- @alt_names = []
23
- @tags = tags
24
- end
25
-
26
- end # class Country
27
-
28
-
29
- end # module Import
30
- end # module SportDb
31
-
@@ -1,18 +0,0 @@
1
- module SportDb
2
- module Import
3
-
4
- class Group
5
- attr_reader :key, :name, :teams
6
-
7
- def initialize( key: nil,
8
- name:,
9
- teams: )
10
- @key = key ## e.g. A,B,C or 1,2,3, - note: always a string or nil
11
- @name = name
12
- @teams = teams
13
- end
14
- end # class Group
15
-
16
- end # module Import
17
- end # module SportDb
18
-
@@ -1,37 +0,0 @@
1
- # encoding: utf-8
2
-
3
- module SportDb
4
- module Import
5
-
6
- class League
7
- attr_reader :key, :name, :country, :intl
8
- attr_accessor :alt_names
9
-
10
- ## special import only attribs
11
- attr_accessor :alt_names_auto ## auto-generated alt names
12
-
13
- def initialize( key:, name:, alt_names: [], alt_names_auto: [],
14
- country: nil, intl: false, clubs: true )
15
- @key = key
16
- @name = name
17
- @alt_names = alt_names
18
- @alt_names_auto = alt_names_auto
19
-
20
- @country = country
21
- @intl = intl
22
- @clubs = clubs
23
- end
24
-
25
- def intl?() @intl == true; end
26
- def national?() @intl == false; end
27
- alias_method :domestic?, :national?
28
-
29
- def clubs?() @clubs == true; end
30
- def national_teams?() @clubs == false; end
31
- alias_method :club?, :clubs?
32
- alias_method :national_team?, :national_teams?
33
-
34
- end # class League
35
-
36
- end # module Import
37
- end # module SportDb
@@ -1,151 +0,0 @@
1
- # encoding: utf-8
2
-
3
- module SportDb
4
- module Import
5
-
6
-
7
- class Match
8
-
9
- attr_reader :date,
10
- :team1, :team2, ## todo/fix: use team1_name, team2_name or similar - for compat with db activerecord version? why? why not?
11
- :score1, :score2, ## full time
12
- :score1i, :score2i, ## half time (first (i) part)
13
- :score1et, :score2et, ## extra time
14
- :score1p, :score2p, ## penalty
15
- :score1agg, :score2agg, ## full time (all legs) aggregated
16
- :winner, # return 1,2,0 1 => team1, 2 => team2, 0 => draw/tie
17
- :round, ## todo/fix: use round_num or similar - for compat with db activerecord version? why? why not?
18
- :leg, ## e.g. '1','2','3','replay', etc. - use leg for marking **replay** too - keep/make leg numeric?! - why? why not?
19
- :stage,
20
- :group,
21
- :conf1, :conf2, ## special case for mls e.g. conference1, conference2 (e.g. west, east, central)
22
- :country1, :country2, ## special case for champions league etc. - uses FIFA country code
23
- :comments
24
-
25
- def initialize( **kwargs )
26
- update( kwargs ) unless kwargs.empty?
27
- end
28
-
29
- def update( **kwargs )
30
- ## note: check with has_key? because value might be nil!!!
31
- @date = kwargs[:date] if kwargs.has_key? :date
32
-
33
- ## todo/fix: use team1_name, team2_name or similar - for compat with db activerecord version? why? why not?
34
- @team1 = kwargs[:team1] if kwargs.has_key? :team1
35
- @team2 = kwargs[:team2] if kwargs.has_key? :team2
36
-
37
- @conf1 = kwargs[:conf1] if kwargs.has_key? :conf1
38
- @conf2 = kwargs[:conf2] if kwargs.has_key? :conf2
39
- @country1 = kwargs[:country1] if kwargs.has_key? :country1
40
- @country2 = kwargs[:country2] if kwargs.has_key? :country2
41
-
42
- ## note: round is a string!!! e.g. '1', '2' for matchday or 'Final', 'Semi-final', etc.
43
- ## todo: use to_s - why? why not?
44
- @round = kwargs[:round] if kwargs.has_key? :round
45
- @stage = kwargs[:stage] if kwargs.has_key? :stage
46
- @leg = kwargs[:leg] if kwargs.has_key? :leg
47
- @group = kwargs[:group] if kwargs.has_key? :group
48
- @comments = kwargs[:comments] if kwargs.has_key? :comments
49
-
50
- if kwargs.has_key?( :score ) ## check all-in-one score struct for convenience!!!
51
- score = kwargs[:score]
52
- if score.nil? ## reset all score attribs to nil!!
53
- @score1 = nil
54
- @score1i = nil
55
- @score1et = nil
56
- @score1p = nil
57
- ## @score1agg = nil
58
-
59
- @score2 = nil
60
- @score2i = nil
61
- @score2et = nil
62
- @score2p = nil
63
- ## @score2agg = nil
64
- else
65
- @score1 = score.score1
66
- @score1i = score.score1i
67
- @score1et = score.score1et
68
- @score1p = score.score1p
69
- ## @score1agg = score.score1agg
70
-
71
- @score2 = score.score2
72
- @score2i = score.score2i
73
- @score2et = score.score2et
74
- @score2p = score.score2p
75
- ## @score2agg = score.score2agg
76
- end
77
- else
78
- @score1 = kwargs[:score1] if kwargs.has_key? :score1
79
- @score1i = kwargs[:score1i] if kwargs.has_key? :score1i
80
- @score1et = kwargs[:score1et] if kwargs.has_key? :score1et
81
- @score1p = kwargs[:score1p] if kwargs.has_key? :score1p
82
- @score1agg = kwargs[:score1agg] if kwargs.has_key? :score1agg
83
-
84
- @score2 = kwargs[:score2] if kwargs.has_key? :score2
85
- @score2i = kwargs[:score2i] if kwargs.has_key? :score2i
86
- @score2et = kwargs[:score2et] if kwargs.has_key? :score2et
87
- @score2p = kwargs[:score2p] if kwargs.has_key? :score2p
88
- @score2agg = kwargs[:score2agg] if kwargs.has_key? :score2agg
89
-
90
- ## note: (always) (auto-)convert scores to integers
91
- @score1 = @score1.to_i if @score1
92
- @score1i = @score1i.to_i if @score1i
93
- @score1et = @score1et.to_i if @score1et
94
- @score1p = @score1p.to_i if @score1p
95
- @score1agg = @score1agg.to_i if @score1agg
96
-
97
- @score2 = @score2.to_i if @score2
98
- @score2i = @score2i.to_i if @score2i
99
- @score2et = @score2et.to_i if @score2et
100
- @score2p = @score2p.to_i if @score2p
101
- @score2agg = @score2agg.to_i if @score2agg
102
- end
103
-
104
- ## todo/fix:
105
- ## gr-greece/2014-15/G1.csv:
106
- ## G1,10/05/15,Niki Volos,OFI,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,
107
- ##
108
-
109
- ## for now score1 and score2 must be present
110
- if @score1.nil? || @score2.nil?
111
- puts "** WARN: missing scores for match:"
112
- pp kwargs
113
- ## exit 1
114
- end
115
-
116
- ## todo/fix: auto-calculate winner
117
- # return 1,2,0 1 => team1, 2 => team2, 0 => draw/tie
118
- ### calculate winner - use 1,2,0
119
- if @score1 && @score2
120
- if @score1 > @score2
121
- @winner = 1
122
- elsif @score2 > @score1
123
- @winner = 2
124
- elsif @score1 == @score2
125
- @winner = 0
126
- else
127
- end
128
- else
129
- @winner = nil # unknown / undefined
130
- end
131
-
132
- self ## note - MUST return self for chaining
133
- end
134
-
135
-
136
-
137
- def over?() true; end ## for now all matches are over - in the future check date!!!
138
- def complete?() true; end ## for now all scores are complete - in the future check scores; might be missing - not yet entered
139
-
140
-
141
- def score_str # pretty print (full time) scores; convenience method
142
- "#{@score1}-#{@score2}"
143
- end
144
-
145
- def scorei_str # pretty print (half time) scores; convenience method
146
- "#{@score1i}-#{@score2i}"
147
- end
148
- end # class Match
149
-
150
- end # module Import
151
- end # module SportDb
@@ -1,220 +0,0 @@
1
- # encoding: utf-8
2
-
3
-
4
- module SportDb
5
- module Import
6
-
7
-
8
- class Matchlist ## todo: find a better name - MatchStats, MatchFixtures, MatchSchedule, ...
9
- ## use MatchCache/Buffer/Summary/Snippet/Segment/List...
10
- ## or MatchAnalyzer/Checker/Proofer/Query - why? why not?
11
- attr_reader :matches # count of matches
12
- ## :name,
13
- ## :goals, # count of (total) goals - use total_goals - why? why not?
14
- ## :teams, -- has its own reader
15
- ## :rounds # note: use if all teams have same match count
16
- ## add last_updated/updated or something - why? why not?
17
-
18
- def initialize( matches )
19
- @matches = matches
20
- end
21
-
22
-
23
- def usage
24
- @usage ||= build_usage( @matches )
25
- @usage
26
- end
27
-
28
- def team_usage() usage.team_usage; end
29
-
30
- def teams
31
- @team_names ||= team_usage.keys.sort
32
- @team_names
33
- end
34
-
35
- def goals() usage.goals; end
36
-
37
- ## note: start_date and end_date might be nil / optional missing!!!!
38
- def start_date?() usage.start_date?; end
39
- def end_date?() usage.end_date?; end
40
-
41
- def start_date() usage.start_date; end
42
- def end_date() usage.end_date; end
43
-
44
- def has_dates?() usage.has_dates?; end
45
- def dates_str() usage.dates_str; end
46
- def days() usage.days; end
47
-
48
-
49
- def rounds() usage.rounds; end
50
-
51
- ## todo: add has_rounds? alias for rounds? too
52
- ## return true if all match_played in team_usage are the same
53
- ## e.g. assumes league with matchday rounds
54
- def rounds?() usage.rounds?; end
55
-
56
- def match_counts() usage.match_counts; end
57
- def match_counts_str() usage.match_counts_str; end
58
-
59
-
60
-
61
- def stage_usage
62
- @stage_usage ||= build_stage_usage( @matches )
63
- @stage_usage
64
- end
65
-
66
- def stages() stage_usage.keys; end ## note: returns empty array for stages for now - why? why not?
67
-
68
-
69
- ############################
70
- # matchlist helpers
71
- private
72
- class StatLine
73
- attr_reader :team_usage,
74
- :matches,
75
- :goals,
76
- :rounds, ## keep rounds - why? why not?
77
- :start_date,
78
- :end_date
79
-
80
- def teams() @team_usage.keys.sort; end ## (auto-)sort here always - why? why not?
81
-
82
- def start_date?() @start_date.nil? == false; end
83
- def end_date?() @end_date.nil? == false; end
84
-
85
- def has_dates?() @start_date && @end_date; end
86
- def dates_str
87
- ## note: start_date/end_date might be optional/missing
88
- if has_dates?
89
- "#{start_date.strftime( '%a %d %b %Y' )} - #{end_date.strftime( '%a %d %b %Y' )}"
90
- else
91
- "??? - ???"
92
- end
93
- end
94
-
95
- def days() end_date.jd - start_date.jd; end
96
-
97
-
98
- def rounds
99
- rounds? ## note: use rounds? to calculate (cache) rounds
100
- @rounds ## note: return number of rounds or nil (for uneven matches played by teams)
101
- end
102
-
103
- ## todo: add has_rounds? alias for rounds? too
104
- def rounds?
105
- ## return true if all match_played in team_usage are the same
106
- ## e.g. assumes league with matchday rounds
107
- if @has_rounds.nil? ## check/todo: if undefined attribute is nil by default??
108
- ## check/calc rounds
109
- ## note: values => matches_played by team
110
- if match_counts.size == 1
111
- @rounds = match_counts[0][0]
112
- else
113
- @rounds = nil
114
- end
115
- @has_rounds = @rounds ? true : false
116
- end
117
- @has_rounds
118
- end
119
-
120
-
121
- def build_match_counts ## use/rename to matches_played - why? why not?
122
- counts = Hash.new(0)
123
- team_usage.values.each do |count|
124
- counts[count] += 1
125
- end
126
-
127
- ## sort (descending) highest usage value first (in returned array)
128
- ## e.g. [[32,8],[31,2]] ## 32 matches by 8 teams, 31 matches by 2 teams etc.
129
- counts.sort_by {|count, usage| -count }
130
- end
131
-
132
- def match_counts
133
- # match counts / nos played per team
134
- @match_counts ||= build_match_counts
135
- @match_counts
136
- end
137
-
138
- def match_counts_str
139
- ## pretty print / formatted match_counts
140
- buf = String.new('')
141
- match_counts.each_with_index do |rec,i|
142
- buf << ' ' if i > 0 ## add (space) separator
143
- buf << "#{rec[0]}×#{rec[1]}"
144
- end
145
- buf
146
- end
147
-
148
-
149
-
150
- def initialize
151
- @matches = 0
152
- @goals = 0
153
-
154
- @start_date = nil
155
- @end_date = nil
156
-
157
- @team_usage = Hash.new(0)
158
-
159
- @match_counts = nil
160
- end
161
-
162
-
163
- def update( match )
164
- @matches += 1 ## match counter
165
-
166
- if match.score1 && match.score2
167
- @goals += match.score1
168
- @goals += match.score2
169
-
170
- ## todo: add after extra time? if knock out (k.o.) - why? why not?
171
- ## make it a flag/opt?
172
- end
173
-
174
- @team_usage[ match.team1 ] += 1
175
- @team_usage[ match.team2 ] += 1
176
-
177
- if match.date
178
- ## return / store date as string as is - why? why not?
179
- date = Date.strptime( match.date, '%Y-%m-%d' )
180
-
181
- @start_date = date if @start_date.nil? || date < @start_date
182
- @end_date = date if @end_date.nil? || date > @end_date
183
- end
184
- end
185
- end # class StatLine
186
-
187
-
188
- ## collect total usage stats (for all matches)
189
- def build_usage( matches )
190
- stat = StatLine.new
191
- matches.each do |match|
192
- stat.update( match )
193
- end
194
- stat
195
- end
196
-
197
- ## collect usage stats by stage (e.g. regular / playoff / etc.)
198
- def build_stage_usage( matches )
199
- stages = {}
200
-
201
- matches.each do |match|
202
- stage_key = if match.stage.nil?
203
- 'Regular' ## note: assume Regular stage if not defined (AND not explicit unknown)
204
- else
205
- match.stage
206
- end
207
-
208
- stages[ stage_key ] ||= StatLine.new
209
- stages[ stage_key ].update( match )
210
- end
211
-
212
- stages
213
- end
214
-
215
- end # class Matchlist
216
-
217
-
218
-
219
- end # module Import
220
- end # module SportDb