sportdb-models 1.15.0 → 1.15.1

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: dfd4954a8fe9eafb1880ac4d2ce1aef869c7e52a
4
- data.tar.gz: 5ccd5c5c17e87a810660342ae15bbb74ec37db24
3
+ metadata.gz: 98fbd2db0f79206ed3154c7ce08822218cea175c
4
+ data.tar.gz: 199637ebcaa4e7fa0477c2eb412400c8303a5c6d
5
5
  SHA512:
6
- metadata.gz: 94a92900f689e5da69210adb12a4e0265dddd14059cb17dc176d6c017e52db032234c7c6bae38db07e65102c92b6383d56cdc0f99d8f99d4ee53ac7d40ed353f
7
- data.tar.gz: 90357b9ea35cb0d8e62d9fbc48096cbf76db007c9443c4e8e81de59e4a50ae18fcd525344648ab30e91fe2665c11120d757c1c16541a78dc6541fab50f1881cd
6
+ metadata.gz: 8d0392d3701140c5af5495115eb0836931f378a0b9e30b33afe8281ceb66dc948176dd89ddf0dd3fbc1d3c255ce49781c4d5335c5988f2187a8ed65fd8db0f29
7
+ data.tar.gz: 6d087ae871a039444129dbc40afa3c0da415539d5a741cea95acd7117e6421adec737adf97f5ac7549f103f8d02d0f7356a9a4c869318cb4d04ed2ef0fa205fe
data/Manifest.txt CHANGED
@@ -18,6 +18,7 @@ lib/sportdb/finders/date.rb
18
18
  lib/sportdb/finders/goals.rb
19
19
  lib/sportdb/finders/scores.rb
20
20
  lib/sportdb/lang.rb
21
+ lib/sportdb/mapper_teams.rb
21
22
  lib/sportdb/matcher.rb
22
23
  lib/sportdb/models.rb
23
24
  lib/sportdb/models/assoc.rb
@@ -86,6 +87,7 @@ test/data/at-austria/2013_14/squads/austria.txt
86
87
  test/data/at-austria/2013_14/squads/salzburg.txt
87
88
  test/data/at-austria/2014_15/1-bundesliga-ii.txt
88
89
  test/data/at-austria/2014_15/1-bundesliga.yml
90
+ test/data/at-austria/2015_16/1-bundesliga-v2.yml
89
91
  test/data/at-austria/2015_16/1-bundesliga.yml
90
92
  test/data/at-austria/2015_16/cup.yml
91
93
  test/data/at-austria/leagues.txt
@@ -0,0 +1,24 @@
1
+ # encoding: UTF-8
2
+
3
+ module SportDb
4
+
5
+ class TeamMapper
6
+ def initialize( recs )
7
+ @mapper = TextUtils::TitleMapper2.new( recs, 'team' )
8
+ end
9
+
10
+ def find_teams!( line ) # Note: returns an array - note: plural! (teamsssss)
11
+ @mapper.find_keys!( line )
12
+ end
13
+
14
+ def find_team!( line ) # Note: returns key (string or nil)
15
+ @mapper.find_key!( line )
16
+ end
17
+
18
+ def map_teams!( line )
19
+ @mapper.map_titles!( line )
20
+ end
21
+ end # class TeamMapper
22
+
23
+ end # module SportDb
24
+
@@ -65,6 +65,7 @@ require 'sportdb/utils_goals'
65
65
  require 'sportdb/matcher'
66
66
  require 'sportdb/calc' # fix/todo: obsolete - replace w/ standings
67
67
  require 'sportdb/standings'
68
+ require 'sportdb/mapper_teams'
68
69
 
69
70
 
70
71
  require 'sportdb/finders/goals' # no: requires FixturesHelpers
@@ -79,29 +79,39 @@ class EventReader
79
79
 
80
80
  ## puts "processing event attrib >>#{key}<< >>#{value}<<..."
81
81
 
82
- if key == 'league'
83
- league = League.find_by_key( value.to_s.strip )
82
+ if key.downcase == 'league' ## note: allow league, League, etc.
83
+ league_key = value.to_s.strip
84
+ ## check if league_key includes uppercase letters (e.g. Deutsche Bundesliga and NOT de etc.)
85
+ if league_key =~ /[A-Z]/
86
+ ## assume league name (NOT league key); try to lookup leauge key in database
87
+ league = League.find_by( title: league_key )
88
+ ## todo: add synonyms/alt names - why? why not??
89
+ else
90
+ ## assume "verbatim/literal" team_key (use as is 1:1)
91
+ league = League.find_by( key: league_key )
92
+ end
84
93
 
85
94
  ## check if it exists
86
- if league.present?
95
+ if league.present? ## todo: just use if league (no present?) ???
87
96
  event_attribs['league_id'] = league.id
88
97
  else
89
- logger.error "league with key >>#{value.to_s.strip}<< missing"
98
+ logger.error "league with key >>#{league_key}<< missing"
90
99
  exit 1
91
100
  end
92
101
 
93
- elsif key == 'season'
94
- season = Season.find_by_key( value.to_s.strip )
102
+ elsif key.downcase == 'season' ## note: allow season, Season, etc.
103
+ season_key = value.to_s.strip
104
+ season = Season.find_by( key: season_key )
95
105
 
96
106
  ## check if it exists
97
107
  if season.present?
98
108
  event_attribs['season_id'] = season.id
99
109
  else
100
- logger.error "season with key >>#{value.to_s.strip}<< missing"
110
+ logger.error "season with key >>#{season_key}<< missing"
101
111
  exit 1
102
112
  end
103
113
 
104
- elsif key == 'start_at' || key == 'begin_at'
114
+ elsif key == 'start_at' || key == 'begin_at' || key.downcase == 'start date'
105
115
 
106
116
  if value.is_a?(DateTime) || value.is_a?(Date)
107
117
  start_at = value
@@ -131,7 +141,7 @@ class EventReader
131
141
  ground_ids = []
132
142
  value.each do |item|
133
143
  ground_key = item.to_s.strip
134
- ground = Ground.find_by_key( ground_key )
144
+ ground = Ground.find_by( key: ground_key )
135
145
  if ground.nil?
136
146
  puts "[warn] ground/stadium w/ key >#{ground_key}< not found; skipping ground"
137
147
  else
@@ -145,7 +155,7 @@ class EventReader
145
155
  ## for now always assume false # todo: fix - use value and convert to boolean if not boolean
146
156
  event_attribs['team3'] = false
147
157
 
148
- elsif key == 'teams' || key.downcase =~ /teams/
158
+ elsif key.downcase =~ /teams/ ## note: allow teams, Teams, 18 teams, 18 Teams etc.
149
159
  ## assume teams value is an array
150
160
 
151
161
  ### check if key includes number of teams; if yes - use for checksum/assert
@@ -211,7 +221,8 @@ class EventReader
211
221
 
212
222
  logger.debug "find event - league_id: #{league_id}, season_id: #{season_id}"
213
223
 
214
- event = Event.find_by_league_id_and_season_id( league_id, season_id )
224
+ event = Event.find_by( league_id: league_id,
225
+ season_id: season_id )
215
226
 
216
227
  ## check if it exists
217
228
  if event.present?
@@ -2,27 +2,6 @@
2
2
 
3
3
  module SportDb
4
4
 
5
-
6
- class TeamMapper
7
- def initialize( recs )
8
- @mapper = TextUtils::TitleMapper2.new( recs, 'team' )
9
- end
10
-
11
- def find_teams!( line ) # Note: returns an array - note: plural! (teamsssss)
12
- @mapper.find_keys!( line )
13
- end
14
-
15
- def find_team!( line ) # Note: returns key (string or nil)
16
- @mapper.find_key!( line )
17
- end
18
-
19
- def map_teams!( line )
20
- @mapper.map_titles!( line )
21
- end
22
- end # class TeamMapper
23
-
24
-
25
-
26
5
  class GameReader
27
6
 
28
7
  include LogUtils::Logging
@@ -1,17 +1,14 @@
1
1
  # encoding: UTF-8
2
2
 
3
3
  ##
4
- #
5
- # todo/fix: cleanup, remove stuff not needed for "simple" rsssf format/style
6
- #
7
- ## for now lets only support leagues with rounds (no cups/knockout rounds n groups)
4
+ ## note: for now lets only support leagues with rounds (no cups/knockout rounds n groups)
8
5
  ## (re)add later when needed (e.g. for playoffs etc.)
9
6
 
10
7
 
11
8
  module SportDb
12
9
 
13
10
 
14
- class RsssfGameReader
11
+ class RsssfGameReader ### todo: rename to RsssfLeagueMatchReader ( or use league/cup option?) - why? why not??
15
12
 
16
13
  include LogUtils::Logging
17
14
 
@@ -19,37 +16,32 @@ class RsssfGameReader
19
16
  # e.g. lets you use Usage instead of Model::Usage
20
17
  include Models
21
18
 
22
- ## value helpers e.g. is_year?, is_taglist? etc.
23
- include TextUtils::ValueHelper
24
-
25
- include FixtureHelpers
26
-
27
19
  ##
28
20
  ## todo: add from_file and from_zip too
29
21
 
30
- def self.from_string( event_key, text )
31
- ### fix - fix -fix:
32
- ## change event to event_or_event_key !!!!! - allow event_key as string passed in
33
- self.new( event_key, text )
22
+ def self.from_string( event_or_event_key, text )
23
+ self.new( event_or_event_key, text )
34
24
  end
35
25
 
36
- def initialize( event_key, text )
37
- ### fix - fix -fix:
38
- ## change event to event_or_event_key !!!!! - allow event_key as string passed in
39
-
26
+ def initialize( event_or_event_key, text )
40
27
  ## todo/fix: how to add opts={} ???
41
- @event_key = event_key
42
- @text = text
28
+ @event_or_event_key = event_or_event_key
29
+ @text = text
43
30
  end
44
31
 
45
32
 
46
33
  def read
47
34
  ## note: assume active activerecord connection
48
- @event = Event.find_by!( key: @event_key )
35
+
36
+ if @event_or_event_key.kind_of?( Event )
37
+ @event= @event_or_event_key
38
+ else ## assume string
39
+ @event = Event.find_by!( key: @event_or_event_key )
40
+ end
49
41
 
50
42
  logger.debug "Event #{@event.key} >#{@event.title}<"
51
43
 
52
- @team_mapper = TextUtils::TitleMapper.new( @event.teams, 'team' )
44
+ @mapper_teams = TeamMapper.new( @event.teams )
53
45
 
54
46
  ## reset cached values
55
47
  @patch_round_ids = []
@@ -57,14 +49,77 @@ class RsssfGameReader
57
49
  @last_round = nil
58
50
  @last_date = nil
59
51
 
60
- ## always use english (en) for now
61
- SportDb.lang.lang = 'en'
62
-
63
52
  reader = LineReader.from_string( @text )
64
53
  parse_fixtures( reader )
65
54
  end # method load_fixtures
66
55
 
67
56
 
57
+
58
+ RSSSF_FT_REGEX = /\b
59
+ (?<score1>\d{1,2})
60
+ -
61
+ (?<score2>\d{1,2})
62
+ \b/x
63
+
64
+ def find_rsssf_scores!( line )
65
+ # e.g. 1-1 or 0-2 or 3-3
66
+
67
+ m = RSSSF_FT_REGEX.match( line )
68
+ if m
69
+ score1 = m[:score1].to_i
70
+ score2 = m[:score2].to_i
71
+
72
+ logger.debug " score: >#{score1}-#{score2}<"
73
+
74
+ line.sub!( m[0], '[SCORE]' )
75
+ else
76
+ score1 = nil
77
+ score2 = nil
78
+ end
79
+
80
+ scores = [score1, score2]
81
+ scores
82
+ end # method find_rsssf_scores!
83
+
84
+
85
+ def find_rsssf_date!( line, opts={} )
86
+ finder = RsssfDateFinder.new
87
+ finder.find!( line, opts )
88
+ end
89
+
90
+
91
+ RSSSF_ROUND_REGEX = /\b
92
+ (?<round>Round)
93
+ \s
94
+ (?<pos>\d{1,3})
95
+ \b/x
96
+
97
+ def is_rsssf_round?( line )
98
+ RSSSF_ROUND_REGEX.match( line ).nil? == false ## match found if not nil
99
+ end
100
+
101
+ def find_rsssf_round!( line )
102
+ ## todo: check if \b works for run on [Apr 13] too ??
103
+ ## todo: allow multiple spaces after round ??
104
+
105
+ m = RSSSF_ROUND_REGEX.match( line )
106
+ if m
107
+ title = m[0] ## note: title is complete match e.g. Round 1, Round 2, etc.
108
+ pos = m[:pos].to_i
109
+
110
+ logger.debug " title: >#{title}<, pos: >#{pos}<"
111
+
112
+ line.sub!( m[0], '[ROUND]' )
113
+ else
114
+ ## fix: add logger.warn no round pos found in line
115
+ title = nil
116
+ pos = nil
117
+ end
118
+
119
+ [title,pos] ## return array; note: [nil,nil] if nothing found
120
+ end # method find_rsssf_round!
121
+
122
+
68
123
  def parse_round_header( line )
69
124
 
70
125
  ## todo/fix:
@@ -76,9 +131,6 @@ class RsssfGameReader
76
131
 
77
132
  logger.debug "parsing round header line: >#{line}<"
78
133
 
79
- ### todo/fix/check: move cut off optional comment in reader for all lines? why? why not?
80
- cut_off_end_of_line_comment!( line ) # cut off optional comment starting w/ #
81
-
82
134
  ## check for date in header first e.g. Round 36 [Jul 20] !!
83
135
  ## avoid "conflict" with getting "wrong" round number from date etc.
84
136
  date = find_rsssf_date!( line, start_at: @event.start_at )
@@ -86,10 +138,7 @@ class RsssfGameReader
86
138
  @last_date = date
87
139
  end
88
140
 
89
- ## todo/check/fix:
90
- # make sure Round of 16 will not return pos 16 -- how? possible?
91
- # add unit test too to verify
92
- pos = find_round_pos!( line )
141
+ title, pos = find_rsssf_round!( line )
93
142
 
94
143
  ## check if pos available; if not auto-number/calculate
95
144
  if pos.nil?
@@ -97,11 +146,6 @@ class RsssfGameReader
97
146
  fail( "round pos required in rsssf; sorry")
98
147
  end
99
148
 
100
- title = find_round_header_title!( line )
101
-
102
- ## Note: use extracted round title for knockout check
103
- ## knockout_flag = is_knockout_round?( title )
104
-
105
149
  logger.debug " line: >#{line}<"
106
150
 
107
151
  ## Note: dummy/placeholder start_at, end_at date
@@ -125,6 +169,7 @@ class RsssfGameReader
125
169
  round_attribs = round_attribs.merge( {
126
170
  event_id: @event.id,
127
171
  pos: pos,
172
+ ## todo: add num e.g. num == pos for round 1, round 2, etc. - why? why not??
128
173
  start_at: Date.parse('1911-11-11'),
129
174
  end_at: Date.parse('1911-11-11')
130
175
  })
@@ -149,9 +194,10 @@ class RsssfGameReader
149
194
  def parse_game( line )
150
195
  logger.debug "parsing game (fixture) line: >#{line}<"
151
196
 
152
- @team_mapper.map_titles!( line )
153
- team1_key = @team_mapper.find_key!( line )
154
- team2_key = @team_mapper.find_key!( line )
197
+ @mapper_teams.map_teams!( line )
198
+ team_keys = @mapper_teams.find_teams!( line )
199
+ team1_key = team_keys[0]
200
+ team2_key = team_keys[1]
155
201
 
156
202
  ## note: if we do NOT find two teams; return false - no match found
157
203
  if team1_key.nil? || team2_key.nil?
@@ -170,9 +216,7 @@ class RsssfGameReader
170
216
  date = @last_date # no date found; (re)use last seen date
171
217
  end
172
218
 
173
- ## fix/todo: use find_rsssf_scores!( line )
174
- ## use rsssf specific score finder!!!
175
- scores = find_scores!( line )
219
+ scores = find_rsssf_scores!( line )
176
220
 
177
221
  logger.debug " line: >#{line}<"
178
222
 
@@ -185,6 +229,9 @@ class RsssfGameReader
185
229
 
186
230
  ### check if games exists
187
231
  ## with this teams in this round if yes only update
232
+ ##
233
+ ## todo: add replay flag (true/false) !!!!!!!!
234
+ ## allows same match fixture in round !!!!!!!!
188
235
  game = Game.find_by( round_id: round.id,
189
236
  team1_id: team1.id,
190
237
  team2_id: team2.id )
@@ -240,9 +287,10 @@ class RsssfGameReader
240
287
  # line with NO teams plus include date e.g.
241
288
  # [Jun 17] etc.
242
289
 
243
- @team_mapper.map_titles!( line )
244
- team1_key = @team_mapper.find_key!( line )
245
- team2_key = @team_mapper.find_key!( line )
290
+ @mapper_teams.map_teams!( line )
291
+ team_keys= @mapper_teams.find_teams!( line )
292
+ team1_key = team_keys[0]
293
+ team2_key = team_keys[1]
246
294
 
247
295
  date = find_rsssf_date!( line, start_at: @event.start_at )
248
296
 
@@ -263,8 +311,7 @@ class RsssfGameReader
263
311
 
264
312
  reader.each_line do |line|
265
313
 
266
- ## fix: use inline/simpler is_rsssf_round?
267
- if is_round?( line )
314
+ if is_rsssf_round?( line )
268
315
  parse_round_header( line )
269
316
  elsif try_parse_game( line )
270
317
  # do nothing here
@@ -21,12 +21,6 @@ module SportDb
21
21
  finder.find!( line, opts )
22
22
  end
23
23
 
24
- def find_rsssf_date!( line, opts={} )
25
- finder = RsssfDateFinder.new
26
- finder.find!( line, opts )
27
- end
28
-
29
-
30
24
  end # module FixtureHelpers
31
25
  end # module SportDb
32
26
 
@@ -4,7 +4,7 @@ module SportDb
4
4
 
5
5
  MAJOR = 1 ## todo: namespace inside version or something - why? why not??
6
6
  MINOR = 15
7
- PATCH = 0
7
+ PATCH = 1
8
8
  VERSION = [MAJOR,MINOR,PATCH].join('.')
9
9
 
10
10
  def self.version
@@ -0,0 +1,20 @@
1
+ #########################################################################
2
+ # Österreichische Bundesliga 2015/16 (104. Meisterschaft / 42. Saison)
3
+
4
+ League: Österr. Bundesliga
5
+ Season: 2015/16
6
+ Start Date: 2015-07-25
7
+
8
+
9
+ 10 Teams:
10
+ - RB Salzburg
11
+ - Rapid Wien
12
+ - Sturm Graz
13
+ - Wolfsberger AC
14
+ - SV Ried
15
+ - Austria Wien
16
+ - Admira Wacker
17
+ - SCR Altach
18
+ - SV Grödig
19
+ - SV Mattersburg ## Aufsteiger
20
+
@@ -15,25 +15,35 @@ class TestEventReaderXX < MiniTest::Test # note: TestEventReader alreay defined
15
15
  WorldDb.delete!
16
16
  SportDb.delete!
17
17
  PersonDb.delete!
18
- end
19
18
 
20
- def test_bl
19
+ ## setup österr. bundesliga
21
20
  at = Country.create!( key: 'at', name: 'Austria', code: 'AUT', pop: 1, area: 1)
22
21
  season = Season.create!( key: '2015/16', title: '2015/16' )
23
- bl = League.create!( key: 'at', title: 'Bundesliga', club: true, country_id: at.id )
22
+ bl = League.create!( key: 'at', title: 'Österr. Bundesliga', club: true, country_id: at.id )
24
23
 
25
24
  ## read teams (required for db key lookup)
26
25
  teamreader = TestTeamReader.from_file( 'at-austria/teams', country_id: at.id )
27
26
  teamreader.read
28
27
  teamreader = TestTeamReader.from_file( 'at-austria/teams_2', country_id: at.id )
29
28
  teamreader.read
29
+ end
30
30
 
31
+ def test_bl
31
32
  r = TestEventReader.from_file( 'at-austria/2015_16/1-bundesliga' )
32
33
  r.read
33
34
 
34
35
  assert true ## if we get here; assume everything ok
35
36
  end
36
37
 
38
+ def test_bl_v2
39
+ r = TestEventReader.from_file( 'at-austria/2015_16/1-bundesliga-v2' )
40
+ r.read
41
+
42
+ assert true ## if we get here; assume everything ok
43
+ end
44
+
45
+
46
+
37
47
  ### fix/todo:
38
48
  ## to be done - add support for Wiener Sportklub (RL Ost) => Wiener Sportklub lookups
39
49
  def xxxx_test_cup
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: sportdb-models
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.15.0
4
+ version: 1.15.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Gerald Bauer
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2015-11-28 00:00:00.000000000 Z
11
+ date: 2015-12-05 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: worlddb-models
@@ -95,6 +95,7 @@ files:
95
95
  - lib/sportdb/finders/goals.rb
96
96
  - lib/sportdb/finders/scores.rb
97
97
  - lib/sportdb/lang.rb
98
+ - lib/sportdb/mapper_teams.rb
98
99
  - lib/sportdb/matcher.rb
99
100
  - lib/sportdb/models.rb
100
101
  - lib/sportdb/models/assoc.rb
@@ -163,6 +164,7 @@ files:
163
164
  - test/data/at-austria/2013_14/squads/salzburg.txt
164
165
  - test/data/at-austria/2014_15/1-bundesliga-ii.txt
165
166
  - test/data/at-austria/2014_15/1-bundesliga.yml
167
+ - test/data/at-austria/2015_16/1-bundesliga-v2.yml
166
168
  - test/data/at-austria/2015_16/1-bundesliga.yml
167
169
  - test/data/at-austria/2015_16/cup.yml
168
170
  - test/data/at-austria/leagues.txt