sportdb-formats 1.0.6 → 1.1.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (57) hide show
  1. checksums.yaml +4 -4
  2. data/Manifest.txt +6 -33
  3. data/Rakefile +2 -5
  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 +45 -13
  10. data/lib/sportdb/formats/league/league_reader.rb +7 -1
  11. data/lib/sportdb/formats/match/match_parser.rb +101 -111
  12. data/lib/sportdb/formats/package.rb +59 -11
  13. data/lib/sportdb/formats/parser_helper.rb +11 -2
  14. data/lib/sportdb/formats/team/club_index.rb +13 -11
  15. data/lib/sportdb/formats/team/club_index_history.rb +134 -0
  16. data/lib/sportdb/formats/team/club_reader_history.rb +203 -0
  17. data/lib/sportdb/formats/team/club_reader_props.rb +20 -5
  18. data/lib/sportdb/formats/version.rb +2 -2
  19. data/test/helper.rb +51 -81
  20. data/test/test_club_index_history.rb +107 -0
  21. data/test/test_club_reader_history.rb +212 -0
  22. data/test/test_datafile_package.rb +1 -1
  23. data/test/test_regex.rb +25 -7
  24. metadata +9 -78
  25. data/lib/sportdb/formats/config.rb +0 -40
  26. data/lib/sportdb/formats/match/match_parser_csv.rb +0 -314
  27. data/lib/sportdb/formats/name_helper.rb +0 -84
  28. data/lib/sportdb/formats/score/score_formats.rb +0 -220
  29. data/lib/sportdb/formats/score/score_parser.rb +0 -202
  30. data/lib/sportdb/formats/season_utils.rb +0 -27
  31. data/lib/sportdb/formats/structs/country.rb +0 -31
  32. data/lib/sportdb/formats/structs/group.rb +0 -18
  33. data/lib/sportdb/formats/structs/league.rb +0 -37
  34. data/lib/sportdb/formats/structs/match.rb +0 -151
  35. data/lib/sportdb/formats/structs/matchlist.rb +0 -220
  36. data/lib/sportdb/formats/structs/round.rb +0 -25
  37. data/lib/sportdb/formats/structs/season.rb +0 -123
  38. data/lib/sportdb/formats/structs/standings.rb +0 -247
  39. data/lib/sportdb/formats/structs/team.rb +0 -150
  40. data/lib/sportdb/formats/structs/team_usage.rb +0 -88
  41. data/test/test_clubs.rb +0 -40
  42. data/test/test_conf.rb +0 -65
  43. data/test/test_csv_match_parser.rb +0 -114
  44. data/test/test_csv_match_parser_utils.rb +0 -20
  45. data/test/test_csv_reader.rb +0 -31
  46. data/test/test_match.rb +0 -30
  47. data/test/test_match_auto.rb +0 -72
  48. data/test/test_match_auto_champs.rb +0 -45
  49. data/test/test_match_auto_euro.rb +0 -37
  50. data/test/test_match_auto_worldcup.rb +0 -61
  51. data/test/test_match_champs.rb +0 -27
  52. data/test/test_match_eng.rb +0 -26
  53. data/test/test_match_euro.rb +0 -27
  54. data/test/test_match_worldcup.rb +0 -27
  55. data/test/test_name_helper.rb +0 -67
  56. data/test/test_scores.rb +0 -122
  57. 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