sportdb-market 0.0.4 → 0.0.5

Sign up to get free protection for your applications and to get access to all the features.
@@ -15,6 +15,16 @@ require 'sportdb/market/reader'
15
15
 
16
16
 
17
17
  module SportDB::Market
18
- puts "hello from sportdb-market, version #{VERSION}"
19
- end
20
18
 
19
+ def self.banner
20
+ "sportdb-market #{VERSION} on Ruby #{RUBY_VERSION} (#{RUBY_RELEASE_DATE}) [#{RUBY_PLATFORM}]"
21
+ end
22
+
23
+ def self.root
24
+ "#{File.expand_path( File.dirname(File.dirname(File.dirname(__FILE__))) )}"
25
+ end
26
+
27
+ puts "SportDB::Market.banner: >>#{SportDB::Market.banner}<<"
28
+ puts "SportDB::Market.root: >>#{SportDB::Market.root}<<"
29
+
30
+ end
@@ -1,2 +1,275 @@
1
1
 
2
- # do something here
2
+ module SportDB::Market
3
+
4
+ ### load quotes from plain text files
5
+
6
+ class Reader
7
+
8
+ ## make models available in sportdb module by default with namespace
9
+ # e.g. lets you use Team instead of Models::Team
10
+ include SportDB::Models
11
+
12
+
13
+ def initialize
14
+ @logger = Logger.new(STDOUT)
15
+ @logger.level = Logger::INFO
16
+ end
17
+
18
+ attr_reader :logger
19
+
20
+ def load_with_include_path( service_key, event_key, name, include_path ) # load from file system
21
+ path = "#{include_path}/#{name}.txt"
22
+
23
+ puts "*** parsing data '#{name}' (#{path})..."
24
+
25
+ code = File.read( path )
26
+
27
+ load_worker( service_key, event_key, code )
28
+ end
29
+
30
+ def load_builtin( service_key, event_key, name ) # load from gem (built-in)
31
+ path = "#{SportDB::Market.root}/db/#{name}.txt"
32
+
33
+ puts "*** parsing data '#{name}' (#{path})..."
34
+
35
+ code = File.read( path )
36
+
37
+ load_worker( service_key, event_key, code )
38
+ end
39
+
40
+ private
41
+ def load_worker( service_key, event_key, data )
42
+
43
+ ## assume active activerecord connection
44
+ ##
45
+
46
+ @service = Service.find_by_key!( service_key )
47
+ @event = Event.find_by_key!( event_key )
48
+
49
+ puts "Quote Service #{@service.key} >#{@service.title}<"
50
+ puts "Event #{@event.key} >#{@event.title}<"
51
+
52
+
53
+ ## build known teams table w/ synonyms e.g.
54
+ #
55
+ # nb: synonyms can be a regex not just a literal string
56
+ # [[ 'wolfsbrug', [ 'VfL Wolfsburg' ]],
57
+ # [ 'augsburg', [ 'FC Augsburg', 'Augi2', 'Augi3' ]],
58
+ # [ 'stuttgart', [ 'VfB Stuttgart' ]] ]
59
+
60
+ ### todo/fix: move known_teams code to model and reuse in readers!!
61
+ ## do NOT duplicate
62
+
63
+ @known_teams = []
64
+
65
+ @event.teams.each_with_index do |team,index|
66
+
67
+ titles = []
68
+ titles << team.title
69
+ titles += team.synonyms.split('|') if team.synonyms.present?
70
+
71
+ ## NB: sort here by length (largest goes first - best match)
72
+ # exclude tag and key (key should always go last)
73
+ titles = titles.sort { |left,right| right.length <=> left.length }
74
+
75
+ titles << team.tag if team.tag.present?
76
+ titles << team.key
77
+
78
+ @known_teams << [ team.key, titles ]
79
+
80
+ puts " Team[#{index+1}] #{team.key} >#{titles.join('|')}<"
81
+ end
82
+
83
+
84
+ parse_quotes( data )
85
+
86
+ puts 'Done.'
87
+
88
+ end # method load
89
+
90
+
91
+ def is_round?( line )
92
+ line =~ /Spieltag|Runde/
93
+ end
94
+
95
+ def find_round_pos!( line )
96
+ regex = /\b(\d+)\b/
97
+
98
+ if line =~ regex
99
+ value = $1.to_i
100
+ puts " pos: >#{value}<"
101
+
102
+ line.sub!( regex, '[POS]' )
103
+
104
+ return value
105
+ else
106
+ return nil
107
+ end
108
+ end
109
+
110
+ def find_quotes!( line )
111
+ # extract quotes triplet from line
112
+ # and return it
113
+ # NB: side effect - removes quotes triplet from line string
114
+
115
+ # e.g. 1,55 3,55 6,44
116
+
117
+ # NB: (?:) is used for non-capturing grouping
118
+
119
+ ## regex1 uses point., e.g. 1.55 for separator
120
+ ## regex2 uses comma-, e.g. 1,55 for separator
121
+
122
+
123
+ regex1 = /[ \t]+(\d{1,3}(?:\.\d{1,3})?)[ \t]+(\d{1,3}(?:\.\d{1,3})?)[ \t]+(\d{1,3}(?:\.\d{1,3})?)/
124
+ regex2 = /[ \t]+(\d{1,3}(?:,\d{1,3})?)[ \t]+(\d{1,3}(?:,\d{1,3})?)[ \t]+(\d{1,3}(?:,\d{1,3})?)/
125
+
126
+ if line =~ regex1
127
+ values = [$1.to_f, $2.to_f, $3.to_f]
128
+ puts " quotes: >#{values.join('|')}<"
129
+
130
+ line.sub!( regex1, ' [QUOTES.EN]' )
131
+
132
+ return values
133
+ elsif line =~ regex2
134
+ values = [$1.tr(',','.').to_f,
135
+ $2.tr(',','.').to_f,
136
+ $3.tr(',','.').to_f]
137
+ puts " quotes: >#{values.join('|')}<"
138
+
139
+ line.sub!( regex2, ' [QUOTES.DE]' )
140
+
141
+ return values
142
+ else
143
+ return nil
144
+ end
145
+ end
146
+
147
+
148
+ def find_team_worker!( line, index )
149
+ regex = /@@oo([^@]+?)oo@@/ # e.g. everything in @@ .... @@ (use non-greedy +? plus all chars but not @, that is [^@])
150
+
151
+ if line =~ regex
152
+ value = "#{$1}"
153
+ puts " team#{index}: >#{value}<"
154
+
155
+ line.sub!( regex, "[TEAM#{index}]" )
156
+
157
+ return $1
158
+ else
159
+ return nil
160
+ end
161
+ end
162
+
163
+ def find_team1!( line )
164
+ find_team_worker!( line, 1 )
165
+ end
166
+
167
+ def find_team2!( line )
168
+ find_team_worker!( line, 2 )
169
+ end
170
+
171
+
172
+ def match_team_worker!( line, key, values )
173
+ values.each do |value|
174
+ regex = Regexp.new( "\\b#{value}\\b" ) # wrap with world boundry (e.g. match only whole words e.g. not wac in wacker)
175
+ if line =~ regex
176
+ puts " match for team >#{key}< >#{value}<"
177
+ # make sure @@oo{key}oo@@ doesn't match itself with other key e.g. wacker, wac, etc.
178
+ line.sub!( regex, "@@oo#{key}oo@@" )
179
+ return true # break out after first match (do NOT continue)
180
+ end
181
+ end
182
+ return false
183
+ end
184
+
185
+ def match_teams!( line )
186
+ @known_teams.each do |rec|
187
+ key = rec[0]
188
+ values = rec[1]
189
+ match_team_worker!( line, key, values )
190
+ end # each known_teams
191
+ end # method translate_teams!
192
+
193
+
194
+ def parse_quotes( data )
195
+
196
+ data.each_line do |line|
197
+
198
+ if line =~ /^\s*#/
199
+ # skip komments and do NOT copy to result (keep comments secret!)
200
+ logger.debug 'skipping comment line'
201
+ next
202
+ end
203
+
204
+ if line =~ /^\s*$/
205
+ # kommentar oder leerzeile überspringen
206
+ logger.debug 'skipping blank line'
207
+ next
208
+ end
209
+
210
+ # remove leading and trailing whitespace
211
+ line = line.strip
212
+
213
+ if is_round?( line )
214
+ puts "parsing round line: >#{line}<"
215
+ pos = find_round_pos!( line )
216
+ puts " line: >#{line}<"
217
+
218
+ @round = Round.find_by_event_id_and_pos!( @event.id, pos )
219
+
220
+
221
+ else
222
+ puts "parsing game (fixture) line: >#{line}<"
223
+
224
+ match_teams!( line )
225
+ team1_key = find_team1!( line )
226
+ team2_key = find_team2!( line )
227
+
228
+ quotes = find_quotes!( line )
229
+
230
+ puts " line: >#{line}<"
231
+
232
+
233
+ ### todo: cache team lookups in hash?
234
+
235
+ team1 = Team.find_by_key!( team1_key )
236
+ team2 = Team.find_by_key!( team2_key )
237
+
238
+ ### check if games exists
239
+ ## with this teams in this round if yes only update
240
+ game = Game.find_by_round_id_and_team1_id_and_team2_id!(
241
+ @round.id, team1.id, team2.id
242
+ )
243
+
244
+ quote_attribs = {
245
+ odds1: quotes[0],
246
+ oddsx: quotes[1],
247
+ odds2: quotes[2]
248
+ }
249
+
250
+ quote = Quote.find_by_service_id_and_game_id( @service.id, game.id )
251
+
252
+ if quote.present?
253
+ puts "*** update quote #{quote.id}:"
254
+ else
255
+ puts "*** create quote:"
256
+ quote = Quote.new
257
+
258
+ more_quote_attribs = {
259
+ service_id: @service.id,
260
+ game_id: game.id
261
+ }
262
+ quote_attribs = quote_attribs.merge( more_quote_attribs )
263
+ end
264
+
265
+ puts quote_attribs.to_json
266
+
267
+ quote.update_attributes!( quote_attribs )
268
+ end
269
+ end # oldlines.each
270
+
271
+ end # method parse_quotes
272
+
273
+ end # class Reader
274
+
275
+ end # module SportDB::Market
@@ -2,5 +2,5 @@
2
2
  module SportDB ; end # forward reference (for hoe require)
3
3
 
4
4
  module SportDB::Market
5
- VERSION = '0.0.4'
5
+ VERSION = '0.0.5'
6
6
  end
metadata CHANGED
@@ -1,13 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: sportdb-market
3
3
  version: !ruby/object:Gem::Version
4
- hash: 23
4
+ hash: 21
5
5
  prerelease:
6
6
  segments:
7
7
  - 0
8
8
  - 0
9
- - 4
10
- version: 0.0.4
9
+ - 5
10
+ version: 0.0.5
11
11
  platform: ruby
12
12
  authors:
13
13
  - Gerald Bauer