sportdb-structs 0.4.1 → 0.5.0
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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +1 -1
- data/Manifest.txt +4 -0
- data/Rakefile +1 -0
- data/lib/sportdb/csv/goal.rb +192 -0
- data/lib/sportdb/csv/goal_parser_csv.rb +28 -0
- data/lib/sportdb/csv/match_parser_csv.rb +490 -0
- data/lib/sportdb/csv/match_status_parser.rb +63 -0
- data/lib/sportdb/structs/country.rb +101 -5
- data/lib/sportdb/structs/league.rb +148 -15
- data/lib/sportdb/structs/match.rb +17 -15
- data/lib/sportdb/structs/round.rb +3 -2
- data/lib/sportdb/structs/team.rb +12 -9
- data/lib/sportdb/structs/version.rb +2 -2
- data/lib/sportdb/structs.rb +40 -3
- metadata +23 -5
@@ -2,9 +2,52 @@
|
|
2
2
|
module Sports
|
3
3
|
|
4
4
|
|
5
|
+
class LeaguePeriod
|
6
|
+
attr_reader :key, :name, :qname, :slug,
|
7
|
+
:prev_name, :start_season, :end_season
|
8
|
+
def initialize( key:, name:, qname:, slug:,
|
9
|
+
prev_name: nil,
|
10
|
+
start_season: nil, end_season: nil )
|
11
|
+
@key = key
|
12
|
+
@name = name
|
13
|
+
@qname = qname
|
14
|
+
@slug = slug
|
15
|
+
@prev_name = prev_name
|
16
|
+
@start_season = start_season
|
17
|
+
@end_season = end_season
|
18
|
+
end
|
19
|
+
|
20
|
+
|
21
|
+
def pretty_print( printer )
|
22
|
+
buf = String.new
|
23
|
+
buf << "<LeaguePeriod"
|
24
|
+
buf << " #{@key}"
|
25
|
+
buf << " (#{@start_season}-#{@end_season})" if @start_season || @end_season
|
26
|
+
buf << " -"
|
27
|
+
buf << " #{@name}"
|
28
|
+
if @name != @qname
|
29
|
+
buf << " | #{@qname}"
|
30
|
+
else
|
31
|
+
buf << "*"
|
32
|
+
end
|
33
|
+
buf << ">"
|
34
|
+
|
35
|
+
printer.text( buf )
|
36
|
+
end
|
37
|
+
end # class LeaguePeriod
|
38
|
+
|
39
|
+
|
40
|
+
################
|
41
|
+
# todo: add a type field -
|
42
|
+
# add a tier field - why? why not?
|
43
|
+
# e.g. league/cup (or national_league, national_cup, intl_cup, etc.?)
|
44
|
+
# e.g. 1st-tier, 2nd-tier, etc.
|
45
|
+
|
46
|
+
|
5
47
|
class League
|
6
48
|
attr_reader :key, :name, :country, :intl
|
7
49
|
attr_accessor :alt_names
|
50
|
+
attr_accessor :periods
|
8
51
|
|
9
52
|
|
10
53
|
def initialize( key:, name:, alt_names: [],
|
@@ -12,12 +55,15 @@ class League
|
|
12
55
|
@key = key
|
13
56
|
@name = name
|
14
57
|
@alt_names = alt_names
|
15
|
-
|
58
|
+
|
16
59
|
@country = country
|
17
60
|
@intl = intl
|
18
61
|
@clubs = clubs
|
62
|
+
|
63
|
+
@periods = [] ## change/rename to history - why? why not?
|
19
64
|
end
|
20
65
|
|
66
|
+
|
21
67
|
def intl?() @intl == true; end
|
22
68
|
def national?() @intl == false; end
|
23
69
|
alias_method :domestic?, :national?
|
@@ -27,35 +73,122 @@ class League
|
|
27
73
|
alias_method :club?, :clubs?
|
28
74
|
alias_method :national_team?, :national_teams?
|
29
75
|
|
30
|
-
|
76
|
+
|
77
|
+
#############################
|
78
|
+
### virtual helpers
|
79
|
+
## 1) codes (returns uniq array of all codes in lowercase
|
80
|
+
## incl. key, code and alt_codes in alt_names)
|
81
|
+
## 2) names (returns uniq array of all names - with language tags stripped)
|
82
|
+
##
|
83
|
+
|
84
|
+
## note: split names into names AND codes
|
85
|
+
## 1) key plus all lower case names are codes
|
86
|
+
## 2) all upper case names are names AND codes
|
87
|
+
## 3) all other names are names
|
88
|
+
|
89
|
+
## only allow asci a to z (why? why not?)
|
90
|
+
## excludes Ö1 or such (what else?)
|
91
|
+
## allow space and dot - why? why not?
|
92
|
+
## e.g. HNL 1
|
93
|
+
## NB I or NB II etc.
|
94
|
+
IS_CODE_N_NAME_RE = %r{^
|
95
|
+
[\p{Lu}0-9. ]+
|
96
|
+
$}x
|
97
|
+
## add space (or /) - why? why not?
|
98
|
+
IS_CODE_RE = %r{^
|
99
|
+
[\p{Ll}0-9.]+
|
100
|
+
$}x
|
101
|
+
|
102
|
+
|
103
|
+
def codes
|
104
|
+
## change/rename to more_codes - why? why?
|
105
|
+
## get reference (tier/canonicial) codes via periods!!!!
|
106
|
+
|
107
|
+
## note - "auto-magically" downcase code (and code'n'name matches)!!
|
108
|
+
## note - do NOT include key as code for now!!!
|
109
|
+
##
|
110
|
+
## todo/check - auto-remove space from code - why? why not?
|
111
|
+
## e.g. NB I, NB II, HNL 1 => NBI, NBII, HBNL1, etc -
|
112
|
+
codes = []
|
113
|
+
alt_names.each do |name|
|
114
|
+
if IS_CODE_N_NAME_RE.match?( name )
|
115
|
+
codes << name.downcase
|
116
|
+
elsif IS_CODE_RE.match?( name )
|
117
|
+
codes << name
|
118
|
+
else ## assume name
|
119
|
+
## do nothing - skip/ignore
|
120
|
+
end
|
121
|
+
end
|
122
|
+
codes.uniq
|
123
|
+
end
|
124
|
+
|
125
|
+
|
126
|
+
include SportDb::NameHelper # pulls-in strip_lang
|
127
|
+
|
128
|
+
def names
|
129
|
+
names = [@name]
|
130
|
+
alt_names.each do |name|
|
131
|
+
if IS_CODE_N_NAME_RE.match?( name )
|
132
|
+
names << name
|
133
|
+
elsif IS_CODE_RE.match?( name )
|
134
|
+
## do nothing - skip/ignore
|
135
|
+
else ## assume name
|
136
|
+
names << strip_lang( name )
|
137
|
+
end
|
138
|
+
end
|
139
|
+
|
140
|
+
## report duplicate names - why? why not
|
141
|
+
## check for duplicates - simple check for now - fix/improve
|
142
|
+
## todo/fix: (auto)remove duplicates - why? why not?
|
143
|
+
count = names.size
|
144
|
+
count_uniq = names.uniq.size
|
145
|
+
if count != count_uniq
|
146
|
+
puts "** !!! ERROR !!! - #{count-count_uniq} duplicate name(s):"
|
147
|
+
pp names
|
148
|
+
pp self
|
149
|
+
exit 1
|
150
|
+
end
|
151
|
+
|
152
|
+
names.uniq
|
153
|
+
end
|
154
|
+
|
155
|
+
|
156
|
+
=begin
|
31
157
|
@alt_names=[],
|
32
158
|
@clubs=true,
|
33
159
|
@country=<Country: at - Austria (AUT)|Österreich [de], fifa|uefa)>,
|
34
160
|
@intl=false,
|
35
161
|
@key="at.1",
|
36
|
-
@name="Bundesliga">,
|
162
|
+
@name="Bundesliga">,
|
37
163
|
=end
|
38
164
|
|
39
|
-
def pretty_print( printer )
|
165
|
+
def pretty_print( printer )
|
40
166
|
buf = String.new
|
41
167
|
buf << "<League"
|
42
168
|
buf << " INTL" if @intl
|
43
|
-
buf << if @clubs
|
44
|
-
" CLUBS"
|
45
|
-
else
|
169
|
+
buf << if @clubs
|
170
|
+
" CLUBS"
|
171
|
+
else
|
46
172
|
" NATIONAL TEAMS"
|
47
|
-
end
|
48
|
-
buf << ": #{@
|
49
|
-
buf << "|#{@alt_names.join('|')}" if @alt_names && !@alt_names.empty?
|
50
|
-
buf << ", #{@country.name} (#{@country.code})" if @country
|
51
|
-
buf << ">"
|
52
|
-
|
53
|
-
printer.text( buf )
|
54
|
-
end
|
173
|
+
end
|
174
|
+
buf << ": #{@name}"
|
55
175
|
|
176
|
+
if @alt_names && !@alt_names.empty?
|
177
|
+
buf << "|"
|
178
|
+
buf << @alt_names.join('|')
|
179
|
+
end
|
56
180
|
|
181
|
+
buf << ", #{@country.name} (#{@country.code})" if @country
|
57
182
|
|
183
|
+
if @periods && !@periods.empty?
|
184
|
+
buf << ", "
|
185
|
+
buf << @periods.map{|period| period.key }.uniq.join('|')
|
186
|
+
end
|
187
|
+
buf << ">"
|
58
188
|
|
189
|
+
printer.text( buf )
|
190
|
+
end
|
59
191
|
end # class League
|
60
192
|
|
193
|
+
|
61
194
|
end # module Sports
|
@@ -181,12 +181,14 @@ class Match
|
|
181
181
|
|
182
182
|
|
183
183
|
def as_json
|
184
|
-
|
184
|
+
#####
|
185
|
+
## note - use string keys (NOT symbol for data keys)
|
186
|
+
## for easier json compatibility
|
185
187
|
data = {}
|
186
188
|
|
187
189
|
## check round
|
188
190
|
if @round
|
189
|
-
data[
|
191
|
+
data['round'] = if round.is_a?( Integer )
|
190
192
|
"Matchday #{@round}"
|
191
193
|
else ## assume string
|
192
194
|
@round
|
@@ -194,28 +196,28 @@ def as_json
|
|
194
196
|
end
|
195
197
|
|
196
198
|
|
197
|
-
data[
|
199
|
+
data['num'] = @num if @num
|
198
200
|
if @date
|
199
201
|
## assume 2020-09-19 date format!!
|
200
|
-
data[
|
202
|
+
data['date'] = @date.is_a?( String ) ? @date : @date.strftime('%Y-%m-%d')
|
201
203
|
|
202
|
-
data[
|
204
|
+
data['time'] = @time if @time
|
203
205
|
end
|
204
206
|
|
205
|
-
data[
|
206
|
-
data[
|
207
|
+
data['team1'] = @team1.is_a?( String ) ? @team1 : @team1.name
|
208
|
+
data['team2'] = @team2.is_a?( String ) ? @team2 : @team2.name
|
207
209
|
|
208
|
-
data[
|
210
|
+
data['score'] = {}
|
209
211
|
|
210
|
-
data[
|
211
|
-
data[
|
212
|
-
data[
|
213
|
-
data[
|
212
|
+
data['score']['ht'] = [@score1i, @score2i] if @score1i && @score2i
|
213
|
+
data['score']['ft'] = [@score1, @score2] if @score1 && @score2
|
214
|
+
data['score']['et'] = [@score1et, @score2et] if @score1et && @score2et
|
215
|
+
data['score']['p'] = [@score1p, @score2p] if @score1p && @score2p
|
214
216
|
|
215
|
-
data[
|
217
|
+
data['status'] = @status if @status
|
216
218
|
|
217
|
-
data[
|
218
|
-
data[
|
219
|
+
data['group'] = @group if @group
|
220
|
+
data['stage'] = @stage if @stage
|
219
221
|
|
220
222
|
=begin
|
221
223
|
"round": "Spieltag 1",
|
@@ -21,13 +21,14 @@ module Sports
|
|
21
21
|
def pretty_print( printer )
|
22
22
|
## todo/check - how to display/format key - use () or not - why? why not?
|
23
23
|
buf = String.new
|
24
|
-
buf << "<Round
|
24
|
+
buf << "<Round"
|
25
|
+
buf << " AUTO" if @auto
|
26
|
+
buf << ": "
|
25
27
|
buf << "(#{@num}) " if @num
|
26
28
|
buf << "#{@name}, "
|
27
29
|
buf << "#{@start_date}"
|
28
30
|
buf << " - #{@end_date}" if @start_date != @end_date
|
29
31
|
buf << " (knockout)" if @knockout
|
30
|
-
buf << " (auto)" if @auto
|
31
32
|
buf << ">"
|
32
33
|
|
33
34
|
printer.text( buf )
|
data/lib/sportdb/structs/team.rb
CHANGED
@@ -64,7 +64,7 @@ class Team # shared base for clubs AND natinal_teams
|
|
64
64
|
|
65
65
|
def initialize( **kwargs )
|
66
66
|
@alt_names = []
|
67
|
-
|
67
|
+
|
68
68
|
update( **kwargs ) unless kwargs.empty?
|
69
69
|
end
|
70
70
|
|
@@ -89,14 +89,14 @@ class NationalTeam < Team
|
|
89
89
|
self ## note - MUST return self for chaining
|
90
90
|
end
|
91
91
|
|
92
|
-
def pretty_print( printer )
|
92
|
+
def pretty_print( printer )
|
93
93
|
buf = String.new
|
94
94
|
buf << "<NationalTeam: #{@name}"
|
95
95
|
## use code from country or from team ???
|
96
|
-
buf << " (#{@code})"
|
96
|
+
buf << " (#{@code})"
|
97
97
|
buf << ">"
|
98
98
|
|
99
|
-
printer.text( buf )
|
99
|
+
printer.text( buf )
|
100
100
|
end
|
101
101
|
end # class NationalTeam
|
102
102
|
|
@@ -121,8 +121,9 @@ class Club < Team
|
|
121
121
|
def geos() @a == nil ? @geos : @a.geos; end
|
122
122
|
|
123
123
|
|
124
|
-
def initialize( **kwargs )
|
125
|
-
|
124
|
+
def initialize( auto: false, **kwargs )
|
125
|
+
@auto = auto
|
126
|
+
super( **kwargs ) ## todo/check - use super only or super() - must it always come first?
|
126
127
|
end
|
127
128
|
|
128
129
|
def update( **kwargs )
|
@@ -135,13 +136,15 @@ class Club < Team
|
|
135
136
|
end
|
136
137
|
|
137
138
|
|
138
|
-
def pretty_print( printer )
|
139
|
+
def pretty_print( printer )
|
139
140
|
buf = String.new
|
140
|
-
buf << "<Club
|
141
|
+
buf << "<Club"
|
142
|
+
buf << " AUTO" if @auto
|
143
|
+
buf << ": #{@name}"
|
141
144
|
buf << " (#{@country.code})" if @country
|
142
145
|
buf << ">"
|
143
146
|
|
144
|
-
printer.text( buf )
|
147
|
+
printer.text( buf )
|
145
148
|
end
|
146
149
|
end # class Club
|
147
150
|
|
data/lib/sportdb/structs.rb
CHANGED
@@ -3,11 +3,16 @@ require 'alphabets' # unaccent, downcase_i18n, variants, ...
|
|
3
3
|
require 'season/formats' # Season.parse, ...
|
4
4
|
require 'score/formats'
|
5
5
|
|
6
|
+
require 'cocos' # pull-in for read_csv & more
|
7
|
+
|
6
8
|
|
7
9
|
###
|
8
10
|
# our own code
|
9
11
|
require_relative 'structs/version' # let version always go first
|
10
12
|
|
13
|
+
## shared support helpers/machinery
|
14
|
+
require_relative 'structs/name_helper'
|
15
|
+
|
11
16
|
require_relative 'structs/country'
|
12
17
|
require_relative 'structs/league'
|
13
18
|
require_relative 'structs/team'
|
@@ -24,9 +29,6 @@ require_relative 'structs/team_usage'
|
|
24
29
|
require_relative 'structs/event_info'
|
25
30
|
|
26
31
|
|
27
|
-
## shared support helpers/machinery
|
28
|
-
require_relative 'structs/name_helper'
|
29
|
-
|
30
32
|
|
31
33
|
##
|
32
34
|
## todo/fix - move "inline" player to structs/player file !!!!
|
@@ -76,7 +78,10 @@ module SportDb
|
|
76
78
|
## add "old" convenience aliases for structs - why? why not?
|
77
79
|
## todo/check: just use include Sports !!!!
|
78
80
|
Country = ::Sports::Country
|
81
|
+
City = ::Sports::City
|
82
|
+
|
79
83
|
League = ::Sports::League
|
84
|
+
LeaguePeriod = ::Sports::LeaguePeriod
|
80
85
|
Group = ::Sports::Group
|
81
86
|
Round = ::Sports::Round
|
82
87
|
Match = ::Sports::Match
|
@@ -99,6 +104,38 @@ end # module SportDb
|
|
99
104
|
|
100
105
|
|
101
106
|
|
107
|
+
###
|
108
|
+
# csv (tabular dataset) support / machinery
|
109
|
+
require_relative 'csv/match_status_parser'
|
110
|
+
require_relative 'csv/goal'
|
111
|
+
require_relative 'csv/goal_parser_csv'
|
112
|
+
require_relative 'csv/match_parser_csv'
|
113
|
+
|
114
|
+
|
115
|
+
### add convenience shortcut helpers
|
116
|
+
module Sports
|
117
|
+
class Match
|
118
|
+
def self.read_csv( path, headers: nil, filters: nil, converters: nil, sep: nil )
|
119
|
+
SportDb::CsvMatchParser.read( path,
|
120
|
+
headers: headers,
|
121
|
+
filters: filters,
|
122
|
+
converters: converters,
|
123
|
+
sep: sep )
|
124
|
+
end
|
125
|
+
|
126
|
+
def self.parse_csv( txt, headers: nil, filters: nil, converters: nil, sep: nil )
|
127
|
+
SportDb::CsvMatchParser.parse( txt,
|
128
|
+
headers: headers,
|
129
|
+
filters: filters,
|
130
|
+
converters: converters,
|
131
|
+
sep: sep )
|
132
|
+
end
|
133
|
+
end # class Match
|
134
|
+
end # module Sports
|
135
|
+
|
136
|
+
|
137
|
+
|
138
|
+
|
102
139
|
#####
|
103
140
|
# note: add Sport and Football convenience alias - why? why not?
|
104
141
|
Sport = Sports
|
metadata
CHANGED
@@ -1,15 +1,29 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: sportdb-structs
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.5.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Gerald Bauer
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2024-
|
11
|
+
date: 2024-12-30 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: cocos
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - ">="
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: 0.4.0
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - ">="
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: 0.4.0
|
13
27
|
- !ruby/object:Gem::Dependency
|
14
28
|
name: alphabets
|
15
29
|
requirement: !ruby/object:Gem::Requirement
|
@@ -78,14 +92,14 @@ dependencies:
|
|
78
92
|
requirements:
|
79
93
|
- - "~>"
|
80
94
|
- !ruby/object:Gem::Version
|
81
|
-
version: '4.
|
95
|
+
version: '4.2'
|
82
96
|
type: :development
|
83
97
|
prerelease: false
|
84
98
|
version_requirements: !ruby/object:Gem::Requirement
|
85
99
|
requirements:
|
86
100
|
- - "~>"
|
87
101
|
- !ruby/object:Gem::Version
|
88
|
-
version: '4.
|
102
|
+
version: '4.2'
|
89
103
|
description: sportdb-structs - sport data structures for matches, scores, leagues,
|
90
104
|
seasons, rounds, groups, teams, clubs and more
|
91
105
|
email: gerald.bauer@gmail.com
|
@@ -100,6 +114,10 @@ files:
|
|
100
114
|
- Manifest.txt
|
101
115
|
- README.md
|
102
116
|
- Rakefile
|
117
|
+
- lib/sportdb/csv/goal.rb
|
118
|
+
- lib/sportdb/csv/goal_parser_csv.rb
|
119
|
+
- lib/sportdb/csv/match_parser_csv.rb
|
120
|
+
- lib/sportdb/csv/match_status_parser.rb
|
103
121
|
- lib/sportdb/structs.rb
|
104
122
|
- lib/sportdb/structs/country.rb
|
105
123
|
- lib/sportdb/structs/event_info.rb
|
@@ -136,7 +154,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
136
154
|
- !ruby/object:Gem::Version
|
137
155
|
version: '0'
|
138
156
|
requirements: []
|
139
|
-
rubygems_version: 3.
|
157
|
+
rubygems_version: 3.5.22
|
140
158
|
signing_key:
|
141
159
|
specification_version: 4
|
142
160
|
summary: sportdb-structs - sport data structures for matches, scores, leagues, seasons,
|