sportdb 1.7.1 → 1.7.2
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/Manifest.txt +5 -4
- data/Rakefile +3 -2
- data/config/{fixtures.de.yml → fixtures/de.yml} +0 -0
- data/config/{fixtures.en.yml → fixtures/en.yml} +0 -0
- data/config/{fixtures.es.yml → fixtures/es.yml} +0 -0
- data/config/{fixtures.pt.yml → fixtures/pt.yml} +0 -0
- data/lib/sportdb.rb +7 -0
- data/lib/sportdb/cli/main.rb +14 -0
- data/lib/sportdb/lang.rb +59 -132
- data/lib/sportdb/models/event.rb +3 -2
- data/lib/sportdb/reader.rb +21 -6
- data/lib/sportdb/schema.rb +6 -0
- data/lib/sportdb/updater.rb +122 -0
- data/lib/sportdb/version.rb +1 -1
- metadata +23 -8
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA1:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 4a7f836cdab30262bf0a6065c1b1f68c6a54f817
|
|
4
|
+
data.tar.gz: 5aea61263d22babceecc7f5dc9b5d8abfc593b87
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 17ef76f90a0bef64d4f5a38366aef3f019adc144aa1f370ce994c64220fe9d37fac0d9e12ea48556e1cc1b6b4460cd3e0c74cb71ae96b43d980e08c1c08bb4dc
|
|
7
|
+
data.tar.gz: 162811a0ed6d0ca322addeb12103f0baccdf57a1f51bb8f6ea73359104a064b0b8a77959360debe8ca21d0287c47e5e2dc6b33710f41ff949e8a73f14f5c7da7
|
data/Manifest.txt
CHANGED
|
@@ -3,10 +3,10 @@ Manifest.txt
|
|
|
3
3
|
README.md
|
|
4
4
|
Rakefile
|
|
5
5
|
bin/sportdb
|
|
6
|
-
config/fixtures
|
|
7
|
-
config/fixtures
|
|
8
|
-
config/fixtures
|
|
9
|
-
config/fixtures
|
|
6
|
+
config/fixtures/de.yml
|
|
7
|
+
config/fixtures/en.yml
|
|
8
|
+
config/fixtures/es.yml
|
|
9
|
+
config/fixtures/pt.yml
|
|
10
10
|
data/seasons.txt
|
|
11
11
|
data/setups/all.yml
|
|
12
12
|
lib/sportdb.rb
|
|
@@ -45,6 +45,7 @@ lib/sportdb/reader.rb
|
|
|
45
45
|
lib/sportdb/schema.rb
|
|
46
46
|
lib/sportdb/stats.rb
|
|
47
47
|
lib/sportdb/title.rb
|
|
48
|
+
lib/sportdb/updater.rb
|
|
48
49
|
lib/sportdb/utils.rb
|
|
49
50
|
lib/sportdb/version.rb
|
|
50
51
|
tasks/test.rb
|
data/Rakefile
CHANGED
|
@@ -23,11 +23,12 @@ Hoe.spec 'sportdb' do
|
|
|
23
23
|
# self.history_file = 'History.md'
|
|
24
24
|
|
|
25
25
|
self.extra_deps = [
|
|
26
|
-
['worlddb', '
|
|
26
|
+
['worlddb', '>= 1.7'], # NB: worlddb already includes
|
|
27
27
|
# - commander
|
|
28
28
|
# - logutils
|
|
29
29
|
# - textutils
|
|
30
|
-
|
|
30
|
+
['fetcher', '>= 0.3'],
|
|
31
|
+
|
|
31
32
|
## 3rd party
|
|
32
33
|
['gli', '>= 2.5.6']
|
|
33
34
|
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
data/lib/sportdb.rb
CHANGED
|
@@ -23,6 +23,7 @@ require 'textutils'
|
|
|
23
23
|
|
|
24
24
|
require 'worlddb'
|
|
25
25
|
|
|
26
|
+
require 'fetcher' # for fetching/downloading fixtures via HTTP/HTTPS etc.
|
|
26
27
|
|
|
27
28
|
# our own code
|
|
28
29
|
|
|
@@ -57,6 +58,7 @@ require 'sportdb/utils'
|
|
|
57
58
|
require 'sportdb/reader'
|
|
58
59
|
require 'sportdb/lang'
|
|
59
60
|
|
|
61
|
+
require 'sportdb/updater'
|
|
60
62
|
require 'sportdb/deleter'
|
|
61
63
|
require 'sportdb/stats'
|
|
62
64
|
|
|
@@ -145,6 +147,11 @@ module SportDb
|
|
|
145
147
|
Deleter.new.run
|
|
146
148
|
end # method delete!
|
|
147
149
|
|
|
150
|
+
def self.update!
|
|
151
|
+
puts '*** update event fixtures...'
|
|
152
|
+
Updater.new.run
|
|
153
|
+
end
|
|
154
|
+
|
|
148
155
|
|
|
149
156
|
def self.stats
|
|
150
157
|
stats = Stats.new
|
data/lib/sportdb/cli/main.rb
CHANGED
|
@@ -195,6 +195,20 @@ command [:load, :l] do |c|
|
|
|
195
195
|
end
|
|
196
196
|
end # command load
|
|
197
197
|
|
|
198
|
+
|
|
199
|
+
desc 'Pull - Auto-update event fixtures from upstream online sources'
|
|
200
|
+
command :pull do |c|
|
|
201
|
+
c.action do |g,o,args|
|
|
202
|
+
|
|
203
|
+
connect_to_db( opts )
|
|
204
|
+
|
|
205
|
+
SportDb.update!
|
|
206
|
+
|
|
207
|
+
puts 'Done.'
|
|
208
|
+
end # action
|
|
209
|
+
end # command pull
|
|
210
|
+
|
|
211
|
+
|
|
198
212
|
desc 'Show logs'
|
|
199
213
|
command :logs do |c|
|
|
200
214
|
c.action do |g,o,args|
|
data/lib/sportdb/lang.rb
CHANGED
|
@@ -6,56 +6,63 @@ class Lang
|
|
|
6
6
|
|
|
7
7
|
include LogUtils::Logging
|
|
8
8
|
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
@lang = 'en' # make default lang english/en
|
|
9
|
+
attr_reader :lang
|
|
12
10
|
|
|
13
|
-
|
|
11
|
+
def initialize
|
|
12
|
+
# fix/todo: load on demand; only if no fixtures loaded/configured use builtin
|
|
13
|
+
load_builtin_words
|
|
14
|
+
end
|
|
14
15
|
|
|
15
|
-
@fixtures_en = YAML.load( File.read_utf8( "#{SportDb.config_path}/fixtures.en.yml" ))
|
|
16
|
-
@fixtures_de = YAML.load( File.read_utf8( "#{SportDb.config_path}/fixtures.de.yml" ))
|
|
17
|
-
@fixtures_es = YAML.load( File.read_utf8( "#{SportDb.config_path}/fixtures.es.yml" ))
|
|
18
16
|
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
'
|
|
22
|
-
'
|
|
17
|
+
def load_builtin_words
|
|
18
|
+
builtin_words = {
|
|
19
|
+
'en' => 'fixtures/en',
|
|
20
|
+
'de' => 'fixtures/de',
|
|
21
|
+
'es' => 'fixtures/es'
|
|
23
22
|
}
|
|
24
23
|
|
|
24
|
+
load_words( builtin_words, SportDb.config_path )
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
def load_words( h, include_path )
|
|
28
|
+
@lang = 'en' # make default lang english/en
|
|
29
|
+
@words = {} # resets fixtures
|
|
30
|
+
@cache = {} # reset cached values
|
|
31
|
+
|
|
32
|
+
h.each_with_index do |(key,value),i|
|
|
33
|
+
name = value
|
|
34
|
+
path = "#{include_path}/#{name}.yml"
|
|
35
|
+
logger.debug( "loading words #{key} (#{i+1}/#{h.size}) in '#{name}' (#{path})..." )
|
|
36
|
+
@words[ key ] = YAML.load( File.read_utf8( path ))
|
|
37
|
+
end
|
|
25
38
|
|
|
26
|
-
@
|
|
27
|
-
@
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
logger.debug "de - #{@words_de.size} words: #{@words_de}"
|
|
32
|
-
logger.debug "es - #{@words_es.size} words: #{@words_es}"
|
|
39
|
+
@classifier = TextUtils::Classifier.new
|
|
40
|
+
@words.each_with_index do |(key,value),i|
|
|
41
|
+
logger.debug "train classifier for #{key} (#{i+1}/#{@words.size})"
|
|
42
|
+
@classifier.train( key, value )
|
|
43
|
+
end
|
|
33
44
|
|
|
45
|
+
@classifier.dump # for debugging dump all words
|
|
34
46
|
end
|
|
35
47
|
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
48
|
+
def classify( text )
|
|
49
|
+
@classifier.classify( text )
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
def classify_file( path )
|
|
53
|
+
@classifier.classify_file( path )
|
|
54
|
+
end
|
|
40
55
|
|
|
41
56
|
def lang=(value)
|
|
42
57
|
logger.debug "setting lang to #{value}"
|
|
43
58
|
|
|
44
59
|
if @lang != value
|
|
60
|
+
|
|
61
|
+
### todo: make reset cached values into method/function for reuse (see load_words)
|
|
45
62
|
# reset cached values on language change
|
|
46
63
|
logger.debug "reseting cached lang values (lang changed from #{@lang} to #{value})"
|
|
47
64
|
|
|
48
|
-
@
|
|
49
|
-
@round = nil
|
|
50
|
-
@knockout_round = nil
|
|
51
|
-
@leg1 = nil
|
|
52
|
-
@leg2 = nil
|
|
53
|
-
|
|
54
|
-
@regex_group = nil
|
|
55
|
-
@regex_round = nil
|
|
56
|
-
@regex_knockout_round = nil
|
|
57
|
-
@regex_leg1 = nil
|
|
58
|
-
@regex_leg2 = nil
|
|
65
|
+
@cache = {}
|
|
59
66
|
end
|
|
60
67
|
|
|
61
68
|
@lang = value
|
|
@@ -64,49 +71,50 @@ class Lang
|
|
|
64
71
|
|
|
65
72
|
|
|
66
73
|
def group
|
|
67
|
-
@group ||= group_getter
|
|
74
|
+
@cache[ :group ] ||= group_getter
|
|
68
75
|
end
|
|
69
76
|
|
|
70
77
|
def round
|
|
71
|
-
@round ||= round_getter
|
|
78
|
+
@cache[ :round ] ||= round_getter
|
|
72
79
|
end
|
|
73
|
-
|
|
80
|
+
|
|
74
81
|
def knockout_round
|
|
75
|
-
@knockout_round ||= knockout_round_getter
|
|
82
|
+
@cache[ :knockout_round ] ||= knockout_round_getter
|
|
76
83
|
end
|
|
77
84
|
|
|
78
85
|
def leg1
|
|
79
|
-
@leg1 ||= leg1_getter
|
|
86
|
+
@cache[ :leg1 ] ||= leg1_getter
|
|
80
87
|
end
|
|
81
88
|
|
|
82
89
|
def leg2
|
|
83
|
-
@leg2 ||= leg2_getter
|
|
90
|
+
@cache[ :leg2 ] ||= leg2_getter
|
|
84
91
|
end
|
|
85
92
|
|
|
86
93
|
|
|
94
|
+
|
|
87
95
|
def regex_group
|
|
88
|
-
@regex_group ||= regex_group_getter
|
|
96
|
+
@cache [ :regex_group ] ||= regex_group_getter
|
|
89
97
|
end
|
|
90
|
-
|
|
98
|
+
|
|
91
99
|
def regex_round
|
|
92
|
-
@regex_round ||= regex_round_getter
|
|
100
|
+
@cache[ :regex_round ] ||= regex_round_getter
|
|
93
101
|
end
|
|
94
|
-
|
|
102
|
+
|
|
95
103
|
def regex_knockout_round
|
|
96
|
-
@regex_knockout_round ||= regex_knockout_round_getter
|
|
104
|
+
@cache[ :regex_knockout_round ] ||= regex_knockout_round_getter
|
|
97
105
|
end
|
|
98
106
|
|
|
99
107
|
def regex_leg1
|
|
100
|
-
@regex_leg1 ||= regex_leg1_getter
|
|
108
|
+
@cache[ :regex_leg1 ] ||= regex_leg1_getter
|
|
101
109
|
end
|
|
102
110
|
|
|
103
111
|
def regex_leg2
|
|
104
|
-
@regex_leg2 ||= regex_leg2_getter
|
|
112
|
+
@cache[ :regex_leg2 ] ||= regex_leg2_getter
|
|
105
113
|
end
|
|
106
114
|
|
|
107
115
|
private
|
|
108
116
|
def group_getter
|
|
109
|
-
h = @
|
|
117
|
+
h = @words[ lang ]
|
|
110
118
|
values = "" # NB: always construct a new string (do NOT use a reference to hash value)
|
|
111
119
|
values << h['group']
|
|
112
120
|
values
|
|
@@ -115,7 +123,7 @@ private
|
|
|
115
123
|
def round_getter
|
|
116
124
|
# e.g. Spieltag|Runde|Achtelfinale|Viertelfinale|Halbfinale|Finale
|
|
117
125
|
|
|
118
|
-
h = @
|
|
126
|
+
h = @words[ lang ]
|
|
119
127
|
values = "" # NB: always construct a new string (do NOT use a reference to hash value)
|
|
120
128
|
values << h['round']
|
|
121
129
|
values << "|" << h['matchday'] ## todo/check: fold round n matchday into one key? why? why not??
|
|
@@ -131,21 +139,21 @@ private
|
|
|
131
139
|
end
|
|
132
140
|
|
|
133
141
|
def leg1_getter
|
|
134
|
-
h = @
|
|
142
|
+
h = @words[ lang ]
|
|
135
143
|
values = "" # NB: always construct a new string (do NOT use a reference to hash value)
|
|
136
144
|
values << h['leg1']
|
|
137
145
|
values
|
|
138
146
|
end
|
|
139
147
|
|
|
140
148
|
def leg2_getter
|
|
141
|
-
h = @
|
|
149
|
+
h = @words[ lang ]
|
|
142
150
|
values = "" # NB: always construct a new string (do NOT use a reference to hash value)
|
|
143
151
|
values << h['leg2']
|
|
144
152
|
values
|
|
145
153
|
end
|
|
146
154
|
|
|
147
155
|
def knockout_round_getter
|
|
148
|
-
h = @
|
|
156
|
+
h = @words[ lang ]
|
|
149
157
|
values = "" # NB: always construct a new string (do NOT use a reference to hash value)
|
|
150
158
|
values << h['round32']
|
|
151
159
|
values << "|" << h['round16']
|
|
@@ -182,88 +190,7 @@ private
|
|
|
182
190
|
/#{leg2}/
|
|
183
191
|
end
|
|
184
192
|
|
|
185
|
-
|
|
186
|
-
def fixtures_hash_to_words_ary( hash )
|
|
187
|
-
ary = []
|
|
188
|
-
hash.each do |key_wild, values_wild|
|
|
189
|
-
key = key_wild.to_s.strip
|
|
190
|
-
values = values_wild.to_s.strip
|
|
191
|
-
|
|
192
|
-
logger.debug "processing key >>#{key}<< with words >>#{values}<<"
|
|
193
|
-
|
|
194
|
-
ary += values.split('|')
|
|
195
|
-
end
|
|
196
|
-
ary
|
|
197
|
-
end
|
|
198
|
-
|
|
199
193
|
end # class Lang
|
|
200
194
|
|
|
201
195
|
|
|
202
|
-
class LangChecker
|
|
203
|
-
|
|
204
|
-
include LogUtils::Logging
|
|
205
|
-
|
|
206
|
-
def initialize
|
|
207
|
-
end
|
|
208
|
-
|
|
209
|
-
def analyze( path )
|
|
210
|
-
# return lang code e.g. en, de, es
|
|
211
|
-
|
|
212
|
-
text = File.read_utf8( path )
|
|
213
|
-
|
|
214
|
-
### todo/fix:
|
|
215
|
-
# remove comment lines and end of line comments from text
|
|
216
|
-
|
|
217
|
-
en = count_words_in_text( SportDb.lang.words_en, text )
|
|
218
|
-
de = count_words_in_text( SportDb.lang.words_de, text )
|
|
219
|
-
es = count_words_in_text( SportDb.lang.words_es, text )
|
|
220
|
-
|
|
221
|
-
lang_counts = [
|
|
222
|
-
[ 'en', en ],
|
|
223
|
-
[ 'de', de ],
|
|
224
|
-
[ 'es', es ]
|
|
225
|
-
]
|
|
226
|
-
|
|
227
|
-
# sort by word count (reverse sort e.g. highest count goes first)
|
|
228
|
-
lang_counts = lang_counts.sort {|l,r| r[1] <=> l[1] }
|
|
229
|
-
|
|
230
|
-
# dump stats
|
|
231
|
-
|
|
232
|
-
logger.debug "lang checker:"
|
|
233
|
-
lang_counts.each_with_index do |item,index|
|
|
234
|
-
## e.g. 1. en: 20 words
|
|
235
|
-
## 2. de: 2 words
|
|
236
|
-
logger.debug " #{index+1}. #{item[0]}: #{item[1]}"
|
|
237
|
-
end
|
|
238
|
-
|
|
239
|
-
logger.info "lang checker - using lang >>#{lang_counts[0][0]}<<"
|
|
240
|
-
|
|
241
|
-
## return lang code w/ highest count
|
|
242
|
-
lang_counts[0][0]
|
|
243
|
-
end
|
|
244
|
-
|
|
245
|
-
private
|
|
246
|
-
def count_word_in_text( word, text )
|
|
247
|
-
count = 0
|
|
248
|
-
pos = text.index( word )
|
|
249
|
-
while pos.nil? == false
|
|
250
|
-
count += 1
|
|
251
|
-
logger.debug "bingo - found >>#{word}<< on pos #{pos}, count: #{count}"
|
|
252
|
-
### todo: check if pos+word.length/size needs +1 or similar
|
|
253
|
-
pos = text.index( word, pos+word.length)
|
|
254
|
-
end
|
|
255
|
-
count
|
|
256
|
-
end
|
|
257
|
-
|
|
258
|
-
def count_words_in_text( words, text )
|
|
259
|
-
count = 0
|
|
260
|
-
words.each do |word|
|
|
261
|
-
count += count_word_in_text( word, text )
|
|
262
|
-
end
|
|
263
|
-
count
|
|
264
|
-
end
|
|
265
|
-
|
|
266
|
-
end # class LangChecker
|
|
267
|
-
|
|
268
|
-
|
|
269
196
|
end # module SportDb
|
data/lib/sportdb/models/event.rb
CHANGED
|
@@ -30,11 +30,12 @@ class Event < ActiveRecord::Base
|
|
|
30
30
|
end
|
|
31
31
|
|
|
32
32
|
def title
|
|
33
|
-
league.title
|
|
33
|
+
"#{league.title} #{season.title}"
|
|
34
34
|
end
|
|
35
35
|
|
|
36
36
|
def full_title # includes season (e.g. year)
|
|
37
|
-
"#
|
|
37
|
+
puts "*** depreciated API call Event#full_title; use Event#title instead; full_title will get removed"
|
|
38
|
+
"#{league.title} #{season.title}"
|
|
38
39
|
end
|
|
39
40
|
|
|
40
41
|
|
data/lib/sportdb/reader.rb
CHANGED
|
@@ -4,6 +4,8 @@ module SportDb
|
|
|
4
4
|
|
|
5
5
|
module Matcher
|
|
6
6
|
|
|
7
|
+
include WorldDb::Matcher
|
|
8
|
+
|
|
7
9
|
def match_leagues_for_country( name, &blk )
|
|
8
10
|
match_xxx_for_country( name, 'leagues', blk )
|
|
9
11
|
end
|
|
@@ -23,8 +25,6 @@ class Reader
|
|
|
23
25
|
## make models available in sportdb module by default with namespace
|
|
24
26
|
# e.g. lets you use Team instead of Models::Team
|
|
25
27
|
include SportDb::Models
|
|
26
|
-
|
|
27
|
-
include WorldDb::Matcher
|
|
28
28
|
include SportDb::Matcher # lets us use match_teams_for_country etc.
|
|
29
29
|
|
|
30
30
|
|
|
@@ -272,6 +272,14 @@ class Reader
|
|
|
272
272
|
reader = HashReaderV2.new( name, include_path )
|
|
273
273
|
|
|
274
274
|
event_attribs = {}
|
|
275
|
+
|
|
276
|
+
## set default sources to basename by convention
|
|
277
|
+
# e.g 2013_14/bl => bl
|
|
278
|
+
# etc.
|
|
279
|
+
# use fixtures/sources: to override default
|
|
280
|
+
|
|
281
|
+
event_attribs[ 'sources' ] = File.basename( name )
|
|
282
|
+
event_attribs[ 'config' ] = File.basename( name ) # name a of .yml file
|
|
275
283
|
|
|
276
284
|
reader.each_typed do |key, value|
|
|
277
285
|
|
|
@@ -325,13 +333,17 @@ class Reader
|
|
|
325
333
|
elsif key == 'team3'
|
|
326
334
|
## for now always assume false # todo: fix - use value and convert to boolean if not boolean
|
|
327
335
|
event_attribs['team3'] = false
|
|
328
|
-
elsif key == 'fixtures'
|
|
329
|
-
|
|
336
|
+
elsif key == 'fixtures' || key == 'sources'
|
|
337
|
+
if value.kind_of?(Array)
|
|
338
|
+
event_attribs['sources'] = value.join(',')
|
|
339
|
+
else # assume plain (single fixture) string
|
|
340
|
+
event_attribs['sources'] = value.to_s
|
|
341
|
+
end
|
|
330
342
|
else
|
|
331
343
|
## todo: add a source location struct to_s or similar (file, line, col)
|
|
332
344
|
logger.error "unknown event attrib #{key}; skipping attrib"
|
|
333
345
|
end
|
|
334
|
-
|
|
346
|
+
|
|
335
347
|
end # each key,value
|
|
336
348
|
|
|
337
349
|
league_id = event_attribs['league_id']
|
|
@@ -356,8 +368,11 @@ class Reader
|
|
|
356
368
|
end # load_event
|
|
357
369
|
|
|
358
370
|
|
|
371
|
+
|
|
359
372
|
def load_fixtures_from_string( event_key, text ) # load from string (e.g. passed in via web form)
|
|
360
373
|
|
|
374
|
+
SportDb.lang.lang = SportDb.lang.classify( text )
|
|
375
|
+
|
|
361
376
|
## todo/fix: move code into LineReader e.g. use LineReader.fromString() - why? why not?
|
|
362
377
|
reader = StringLineReader.new( text )
|
|
363
378
|
|
|
@@ -385,7 +400,7 @@ class Reader
|
|
|
385
400
|
|
|
386
401
|
logger.info "parsing data '#{name}' (#{path})..."
|
|
387
402
|
|
|
388
|
-
SportDb.lang.lang =
|
|
403
|
+
SportDb.lang.lang = SportDb.lang.classify_file( path )
|
|
389
404
|
|
|
390
405
|
reader = LineReader.new( path )
|
|
391
406
|
|
data/lib/sportdb/schema.rb
CHANGED
|
@@ -128,6 +128,12 @@ create_table :events do |t|
|
|
|
128
128
|
t.date :end_at # make it required??? # NB: only use date (w/o time)
|
|
129
129
|
t.boolean :team3, :null => false, :default => true ## e.g. Champions League has no 3rd place (only 1st and 2nd/final)
|
|
130
130
|
|
|
131
|
+
#### track 1-n sources (from repos) - # todo move to its own table later
|
|
132
|
+
## NB: relative to event.yml - use mapper to "resolve" to full path w/ repo; use league+season keys
|
|
133
|
+
t.string :sources # e.g. cup or bl,bl_ii # NB: for now store all in on string separated by comma
|
|
134
|
+
t.string :config # e.g. cup or bl # e.g assumes cup.yml, bl.yml etc. for now
|
|
135
|
+
|
|
136
|
+
|
|
131
137
|
t.timestamps
|
|
132
138
|
end
|
|
133
139
|
|
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
|
|
2
|
+
module SportDb
|
|
3
|
+
|
|
4
|
+
class Updater
|
|
5
|
+
|
|
6
|
+
include LogUtils::Logging
|
|
7
|
+
|
|
8
|
+
######
|
|
9
|
+
# NB: make models available in sportdb module by default with namespace
|
|
10
|
+
# e.g. lets you use Team instead of Models::Team
|
|
11
|
+
include SportDb::Models
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
def map_event_to_dlurl( event )
|
|
15
|
+
|
|
16
|
+
league_key = event.league.key
|
|
17
|
+
season_key = event.season.key
|
|
18
|
+
|
|
19
|
+
repo_path, folder_path = map_key_to_repo_n_folder_path( league_key )
|
|
20
|
+
return nil if repo_path.nil? # no match/mapping found; cancel download
|
|
21
|
+
|
|
22
|
+
season_path = season_key.gsub( '/', '_') # convert 2013/14 to 2013_14
|
|
23
|
+
|
|
24
|
+
###
|
|
25
|
+
# e.g. https://raw.github.com/openfootball/at-austria/master/2013_14/bl.txt
|
|
26
|
+
|
|
27
|
+
dlurl = "https://raw.github.com/openfootball/#{repo_path}/master"
|
|
28
|
+
dlurl << "/#{folder_path}" if folder_path.present?
|
|
29
|
+
dlurl << "/#{season_path}"
|
|
30
|
+
dlurl
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
def map_key_to_repo_n_folder_path( key )
|
|
35
|
+
|
|
36
|
+
### allow * for regex match w/ .+
|
|
37
|
+
map = [
|
|
38
|
+
[ 'at', 'at-austria' ],
|
|
39
|
+
[ 'at.*', 'at-austria' ],
|
|
40
|
+
[ 'de', 'de-deutschland' ],
|
|
41
|
+
[ 'be', 'europe', 'be-belgium' ], # NB: europe/be-belgium
|
|
42
|
+
[ 'cl', 'europe' ],
|
|
43
|
+
[ 'world.*', 'world-cup' ]]
|
|
44
|
+
|
|
45
|
+
map.each do |entry|
|
|
46
|
+
pattern = entry[0]
|
|
47
|
+
path = [ entry[1], entry[2] ] # repo n folder path
|
|
48
|
+
|
|
49
|
+
if pattern.index( '*' ).nil? # match just plain string (no wildcard *)
|
|
50
|
+
return path if key == pattern
|
|
51
|
+
else
|
|
52
|
+
# assume regex match
|
|
53
|
+
regex = pattern.gsub( '.', '\.' ).gsub( '*', '.+' )
|
|
54
|
+
return path if key =~ /#{regex}/
|
|
55
|
+
end
|
|
56
|
+
end
|
|
57
|
+
nil # return nil; no match found
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
def update_event( event )
|
|
61
|
+
puts "update event >>#{event.title}<< (#{event.league.key}+#{event.season.key})"
|
|
62
|
+
|
|
63
|
+
dlbase = map_event_to_dlurl( event )
|
|
64
|
+
if dlbase.nil?
|
|
65
|
+
puts " skip download; no download source mapping found"
|
|
66
|
+
return # cancel download; no mapping found
|
|
67
|
+
end
|
|
68
|
+
|
|
69
|
+
puts " using dlbase >>#{dlbase}<<"
|
|
70
|
+
|
|
71
|
+
if event.sources.nil?
|
|
72
|
+
puts " skip download; no download event source configured/found"
|
|
73
|
+
return
|
|
74
|
+
end
|
|
75
|
+
|
|
76
|
+
sources = event.sources.gsub(' ','').split(',') # NB: remove all blanks (leading,trailing,inside)
|
|
77
|
+
sources.each_with_index do |source,i|
|
|
78
|
+
dlurl = "#{dlbase}/#{source}.txt"
|
|
79
|
+
puts " downloading source (#{i+1}/#{sources.length}) >>#{dlurl}<< ..." # todo/check: use size for ary or length - does it matter?
|
|
80
|
+
|
|
81
|
+
# download fixtures into string
|
|
82
|
+
text = Fetcher.read( dlurl )
|
|
83
|
+
|
|
84
|
+
logger.debug "text.encoding.name (before): #{text.encoding.name}"
|
|
85
|
+
|
|
86
|
+
###
|
|
87
|
+
# NB: Net::HTTP will NOT set encoding UTF-8 etc.
|
|
88
|
+
# will mostly be ASCII
|
|
89
|
+
# - try to change encoding to UTF-8 ourselves
|
|
90
|
+
|
|
91
|
+
#####
|
|
92
|
+
# NB: ASCII-8BIT == BINARY == Encoding Unknown; Raw Bytes Here
|
|
93
|
+
|
|
94
|
+
## NB:
|
|
95
|
+
# for now "hardcoded" to utf8 - what else can we do?
|
|
96
|
+
# - note: force_encoding will NOT change the chars only change the assumed encoding w/o translation
|
|
97
|
+
text = text.force_encoding( Encoding::UTF_8 )
|
|
98
|
+
logger.debug "text.encoding.name (after): #{text.encoding.name}"
|
|
99
|
+
|
|
100
|
+
|
|
101
|
+
puts " importing/reading source..."
|
|
102
|
+
reader= Reader.new( '/tmp' ) # passing dummy include_path (not needed for reading from string)
|
|
103
|
+
|
|
104
|
+
## todo/fix: offer a version that lets us pass in event (not event.key)
|
|
105
|
+
# no need for another event lookup
|
|
106
|
+
reader.load_fixtures_from_string( event.key, text )
|
|
107
|
+
end
|
|
108
|
+
end
|
|
109
|
+
|
|
110
|
+
|
|
111
|
+
def run
|
|
112
|
+
# for now update all events (fixtures only) - not *.yml
|
|
113
|
+
|
|
114
|
+
Event.all.each do |event|
|
|
115
|
+
update_event( event )
|
|
116
|
+
end
|
|
117
|
+
|
|
118
|
+
end
|
|
119
|
+
|
|
120
|
+
end # class Updater
|
|
121
|
+
|
|
122
|
+
end # module SportDb
|
data/lib/sportdb/version.rb
CHANGED
metadata
CHANGED
|
@@ -1,29 +1,43 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: sportdb
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 1.7.
|
|
4
|
+
version: 1.7.2
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Gerald Bauer
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: bin
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date: 2013-08-
|
|
11
|
+
date: 2013-08-29 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: worlddb
|
|
15
15
|
requirement: !ruby/object:Gem::Requirement
|
|
16
16
|
requirements:
|
|
17
|
-
- -
|
|
17
|
+
- - ! '>='
|
|
18
18
|
- !ruby/object:Gem::Version
|
|
19
19
|
version: '1.7'
|
|
20
20
|
type: :runtime
|
|
21
21
|
prerelease: false
|
|
22
22
|
version_requirements: !ruby/object:Gem::Requirement
|
|
23
23
|
requirements:
|
|
24
|
-
- -
|
|
24
|
+
- - ! '>='
|
|
25
25
|
- !ruby/object:Gem::Version
|
|
26
26
|
version: '1.7'
|
|
27
|
+
- !ruby/object:Gem::Dependency
|
|
28
|
+
name: fetcher
|
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
|
30
|
+
requirements:
|
|
31
|
+
- - ! '>='
|
|
32
|
+
- !ruby/object:Gem::Version
|
|
33
|
+
version: '0.3'
|
|
34
|
+
type: :runtime
|
|
35
|
+
prerelease: false
|
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
37
|
+
requirements:
|
|
38
|
+
- - ! '>='
|
|
39
|
+
- !ruby/object:Gem::Version
|
|
40
|
+
version: '0.3'
|
|
27
41
|
- !ruby/object:Gem::Dependency
|
|
28
42
|
name: gli
|
|
29
43
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -81,10 +95,10 @@ files:
|
|
|
81
95
|
- README.md
|
|
82
96
|
- Rakefile
|
|
83
97
|
- bin/sportdb
|
|
84
|
-
- config/fixtures
|
|
85
|
-
- config/fixtures
|
|
86
|
-
- config/fixtures
|
|
87
|
-
- config/fixtures
|
|
98
|
+
- config/fixtures/de.yml
|
|
99
|
+
- config/fixtures/en.yml
|
|
100
|
+
- config/fixtures/es.yml
|
|
101
|
+
- config/fixtures/pt.yml
|
|
88
102
|
- data/seasons.txt
|
|
89
103
|
- data/setups/all.yml
|
|
90
104
|
- lib/sportdb.rb
|
|
@@ -123,6 +137,7 @@ files:
|
|
|
123
137
|
- lib/sportdb/schema.rb
|
|
124
138
|
- lib/sportdb/stats.rb
|
|
125
139
|
- lib/sportdb/title.rb
|
|
140
|
+
- lib/sportdb/updater.rb
|
|
126
141
|
- lib/sportdb/utils.rb
|
|
127
142
|
- lib/sportdb/version.rb
|
|
128
143
|
- tasks/test.rb
|