sportdb 1.9.5 → 1.9.6

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,37 +0,0 @@
1
-
2
- $base-font-family: "Helvetica Neue", Helvetica, Arial, sans-serif;
3
-
4
- body
5
- {
6
- font-family: $base-font-family;
7
- }
8
-
9
-
10
- a {
11
- color: black;
12
- text-decoration: none;
13
-
14
- &:hover {
15
- color: black;
16
- background-color: aqua;
17
- text-decoration: underline;
18
- }
19
-
20
- &:visited { color: black; }
21
- }
22
-
23
-
24
- /////////////////////////
25
- // version / powered_by
26
-
27
- .version
28
- {
29
- text-align: center;
30
- margin-top: 10px;
31
- color: grey;
32
-
33
- a, span {
34
- font-size: 12px;
35
- color: grey
36
- }
37
- }
@@ -1,184 +0,0 @@
1
-
2
- module SportDb
3
-
4
-
5
- class Server < Sinatra::Base
6
-
7
- def self.banner
8
- "sportdb-service/#{VERSION} on Ruby #{RUBY_VERSION} (#{RUBY_RELEASE_DATE}) [#{RUBY_PLATFORM}] on Sinatra/#{Sinatra::VERSION} (#{ENV['RACK_ENV']})"
9
- end
10
-
11
- ######
12
- # allow cross site json requests (e.g. url posting on rubyflow - avoid crash!!)
13
- # see
14
- # http://www.sinatrarb.com/intro.html#Configuring attack protection
15
- # todo: only switch off jsoncrfl ??? do NOT disable all
16
-
17
- disable :protection
18
-
19
- PUBLIC_FOLDER = "#{SportDb.root}/lib/sportdb/service/public"
20
- VIEWS_FOLDER = "#{SportDb.root}/lib/sportdb/service/views"
21
-
22
- puts "[boot] setting sportdb api public folder to: #{PUBLIC_FOLDER}"
23
- puts "[boot] setting sportdb api views folder to: #{VIEWS_FOLDER}"
24
-
25
- set :public_folder, PUBLIC_FOLDER # set up the static dir (with images/js/css inside)
26
- set :views, VIEWS_FOLDER # set up the views dir
27
-
28
- set :static, true # set up static file routing
29
-
30
- #####################
31
- # Models
32
-
33
- include Models
34
-
35
- ##################
36
- # Helpers
37
-
38
-
39
- def path_prefix
40
- request.env['SCRIPT_NAME']
41
- end
42
-
43
- ##############################################
44
- # Controllers / Routing / Request Handlers
45
-
46
-
47
- get '/' do
48
- erb :index
49
- end
50
-
51
- get '/d*' do
52
- erb :debug
53
- end
54
-
55
- get '/rounds/:q' do |q|
56
-
57
- #################
58
- # todo/check:
59
- # what to do for special case with postponed games/matches??
60
- # if match postponed round end_at date also gets moved back!
61
- # use a different end_at date for original end_at e.g add a new field? why? why not?
62
- # -- if round out of original scope mark as postponed (e.g. spielrunde 5 - nachtrag!)
63
-
64
- rounds = []
65
-
66
- if q =~ /(\d{1,2})\.(\d{1,2})\.(\d{4})/
67
- t = Time.new( $3.to_i, $2.to_i, $1.to_i )
68
- elsif q =~ /(\d{4})\.(\d{1,2})\.(\d{1,2})/
69
- t = Time.new( $1.to_i, $2.to_i, $3.to_i )
70
- else
71
- t = Time.now # no match - assume today's/current date
72
- end
73
-
74
- t_00_00 = t.beginning_of_day
75
- t_23_59 = t.end_of_day
76
-
77
- ## NB: sqlite stores time too
78
- # use 00_00 and 23_59 to make sure queries work with hours too
79
-
80
- current_rounds = Round.where( 'start_at <= ? and end_at >= ?', t_23_59, t_00_00 )
81
- current_rounds.each do |r|
82
- rounds << { pos: r.pos,
83
- title: r.title,
84
- start_at: r.start_at.strftime('%Y/%m/%d'),
85
- end_at: r.end_at.strftime('%Y/%m/%d'),
86
- event: { key: r.event.key,
87
- title: r.event.full_title }}
88
- end
89
-
90
- data = { rounds: rounds }
91
-
92
- json_or_jsonp( data )
93
- end
94
-
95
-
96
- get '/event/:key/teams' do |key|
97
- # NB: change en.2012_13 to en.2012/13
98
- event = Event.find_by_key!( key.tr('_', '/') )
99
-
100
- teams = []
101
- event.teams.each do |t|
102
- teams << { key: t.key, title: t.title, code: t.code }
103
- end
104
-
105
- data = { event: { key: event.key, title: event.full_title }, teams: teams }
106
-
107
- json_or_jsonp( data )
108
- end
109
-
110
-
111
- get '/event/:key/rounds' do |key|
112
- # NB: change en.2012_13 to en.2012/13
113
- event = Event.find_by_key!( key.tr('_', '/') )
114
-
115
- rounds = []
116
- event.rounds.each do |r|
117
- rounds << { pos: r.pos, title: r.title,
118
- start_at: r.start_at.strftime('%Y/%m/%d'),
119
- end_at: r.end_at.strftime('%Y/%m/%d') }
120
- end
121
-
122
- data = { event: { key: event.key, title: event.full_title }, rounds: rounds }
123
-
124
- json_or_jsonp( data )
125
- end
126
-
127
-
128
- get '/event/:key/round/:pos' do |key,pos|
129
- # NB: change en.2012_13 to en.2012/13
130
- event = Event.find_by_key!( key.tr('_', '/') )
131
-
132
- if pos =~ /\d+/
133
- round = Round.find_by_event_id_and_pos!( event.id, pos )
134
- else # assume last from today's date (use last/today/etc. - must be non-numeric key)
135
- t_23_59 = Time.now.end_of_day
136
- round = Round.where( event_id: event.id ).where( 'start_at <= ?', t_23_59 ).order( 'pos' ).last
137
- if round.nil? # assume all rounds in the future; display first upcoming one
138
- round = Round.where( event_id: event.id ).order('pos').first
139
- end
140
- end
141
-
142
- games = []
143
- round.games.each do |g|
144
- games << { team1_key: g.team1.key, team1_title: g.team1.title, team1_code: g.team1.code,
145
- team2_key: g.team2.key, team2_title: g.team2.title, team2_code: g.team2.code,
146
- play_at: g.play_at.strftime('%Y/%m/%d'),
147
- score1: g.score1, score2: g.score2,
148
- score1ot: g.score1ot, score2ot: g.score2ot,
149
- score1p: g.score1p, score2p: g.score2p
150
- }
151
- end
152
-
153
- data = { event: { key: event.key, title: event.full_title },
154
- round: { pos: round.pos, title: round.title,
155
- start_at: round.start_at.strftime('%Y/%m/%d'),
156
- end_at: round.end_at.strftime('%Y/%m/%d')
157
- },
158
- games: games }
159
-
160
- json_or_jsonp( data )
161
- end
162
-
163
-
164
- ### helper for json or jsonp response (depending on callback para)
165
-
166
- private
167
- def json_or_jsonp( data )
168
- callback = params.delete('callback')
169
- response = ''
170
-
171
- if callback
172
- content_type :js
173
- response = "#{callback}(#{data.to_json})"
174
- else
175
- content_type :json
176
- response = data.to_json
177
- end
178
-
179
- response
180
- end
181
-
182
- end # class Server
183
-
184
- end # module SportDb
@@ -1,17 +0,0 @@
1
-
2
- <h3>Debug</h3>
3
-
4
- <pre>
5
- request.scheme <%= request.scheme %>
6
- request.script_name <%= request.script_name %>
7
- request.path_info <%= request.path_info %>
8
- request.port <%= request.port %>
9
- request.request_method <%= request.request_method %>
10
- request.query_string <%= request.query_string %>
11
- request.host <%= request.host %>
12
- request.referrer <%= request.referrer %>
13
- request.user_agent <%= request.user_agent %>
14
- request.url <%= request.url %>
15
- request.path <%= request.path %>
16
- request.ip <%= request.ip %>
17
- </pre>
@@ -1,7 +0,0 @@
1
- <div class='version'>
2
- <a href="http://groups.google.com/group/opensport">Questions? Comments?</a> |
3
- <a href="https://github.com/geraldb/world.db.ruby">world.db/<%= WorldDb::VERSION %></a>,
4
- <a href="https://github.com/geraldb/sport.db.ruby">sport.db/<%= SportDb::VERSION %></a> -
5
- <span>Ruby/<%= "#{RUBY_VERSION} (#{RUBY_RELEASE_DATE}/#{RUBY_PLATFORM})" %> on</span>
6
- <span>Sinatra/<%= Sinatra::VERSION %> (<%= ENV['RACK_ENV'] %>)</span>
7
- </div>
@@ -1,2 +0,0 @@
1
-
2
- <%= erb :'_debug' %>
@@ -1,6 +0,0 @@
1
- <h1>sport.db HTTP JSON(P) API</h1>
2
-
3
-
4
- <% if params[:debug].present? %>
5
- <%= erb :'_debug' %>
6
- <% end %>
@@ -1,15 +0,0 @@
1
- <!DOCTYPE html>
2
- <html>
3
- <head>
4
- <meta charset='UTF-8'>
5
- <title>sport.db.api // sport.db HTTP JSON(P) API // sport.db Web Service</title>
6
- <link href="<%= url('/style.css') %>" rel='stylesheet'>
7
- </head>
8
- <body>
9
-
10
- <%= yield %>
11
-
12
- <%= erb :'_version' %>
13
-
14
- </body>
15
- </html>
@@ -1,152 +0,0 @@
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 Model::Team
11
- include 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
-
21
- return nil if repo_path.nil? # no match/mapping found; cancel download
22
-
23
- season_path = season_key.gsub( '/', '_') # convert 2013/14 to 2013_14
24
-
25
- #####
26
- # quick hack!!!!
27
- # - find something better e.g. more generic/easy to configure etc.
28
- if league_key == 'world' # world cup repo mappings include host country e.g. 2014--brazil etc.
29
- season_path = '2006--germany' if season_path == '2006'
30
- season_path = '2010--south-africa' if season_path == '2010'
31
- season_path = '2014--brazil' if season_path == '2014'
32
- end
33
-
34
- ###
35
- # e.g. https://raw.github.com/openfootball/at-austria/master/2013_14
36
-
37
- dlurl = "https://raw.github.com/openfootball/#{repo_path}/master"
38
- dlurl << "/#{folder_path}" if folder_path.present?
39
- dlurl << "/#{season_path}"
40
- dlurl
41
- end
42
-
43
-
44
- def map_key_to_repo_n_folder_path( key )
45
-
46
- ### allow * for regex match w/ .+
47
- map = [
48
- [ 'at', 'at-austria' ],
49
- [ 'at.*', 'at-austria' ],
50
- [ 'de', 'de-deutschland' ],
51
- [ 'de.*', 'de-deutschland' ],
52
- [ 'en', 'en-england' ],
53
- [ 'es', 'es-espana' ],
54
- [ 'it', 'it-italy' ],
55
- [ 'be', 'europe', 'be-belgium' ], # NB: europe/be-belgium
56
- [ 'ro', 'europe', 'ro-romania' ],
57
- [ 'cl', 'europe-champions-league' ],
58
- [ 'el', 'europe-champions-league' ],
59
- [ 'br', 'br-brazil' ],
60
- [ 'mx', 'mx-mexico' ], # todo: add mx.* for clausura etc ??
61
- [ 'euro', 'euro-cup' ],
62
- [ 'world', 'world-cup' ],
63
- [ 'world.*', 'world-cup' ]]
64
-
65
- map.each do |entry|
66
- pattern = entry[0]
67
- path = [ entry[1], entry[2] ] # repo n folder path
68
-
69
- if pattern.index( '*' ).nil? # match just plain string (no wildcard *)
70
- return path if key == pattern
71
- else
72
- # assume regex match
73
- regex = pattern.gsub( '.', '\.' ).gsub( '*', '.+' )
74
- return path if key =~ /#{regex}/
75
- end
76
- end
77
- nil # return nil; no match found
78
- end
79
-
80
- def update_event( event )
81
- logger.info "update event >>#{event.title}<< (#{event.league.key}+#{event.season.key})"
82
-
83
- dlbase = map_event_to_dlurl( event )
84
- if dlbase.nil?
85
- logger.warn " [Updater] skip download; no download source mapping found for >#{event.key}<"
86
- return # cancel download; no mapping found
87
- end
88
-
89
- puts " using dlbase >>#{dlbase}<<"
90
-
91
- if event.sources.nil?
92
- logger.warn " [Updater] skip download; no download event source configured/found for >#{event.key}<"
93
- return
94
- end
95
-
96
- sources = event.sources.gsub(' ','').split(',') # NB: remove all blanks (leading,trailing,inside)
97
-
98
-
99
- text_ary = [] # array of fixtures (text)
100
-
101
- ## collect all fixtures (text)
102
- sources.each_with_index do |source,i|
103
- dlurl = "#{dlbase}/#{source}.txt"
104
- logger.info " downloading source (#{i+1}/#{sources.length}) >>#{dlurl}<< ..." # todo/check: use size for ary or length - does it matter?
105
-
106
- # download fixtures into string
107
- text = Fetcher.read( dlurl )
108
-
109
- logger.debug "text.encoding.name (before): #{text.encoding.name}"
110
-
111
- ###
112
- # NB: Net::HTTP will NOT set encoding UTF-8 etc.
113
- # will mostly be ASCII
114
- # - try to change encoding to UTF-8 ourselves
115
-
116
- #####
117
- # NB: ASCII-8BIT == BINARY == Encoding Unknown; Raw Bytes Here
118
-
119
- ## NB:
120
- # for now "hardcoded" to utf8 - what else can we do?
121
- # - note: force_encoding will NOT change the chars only change the assumed encoding w/o translation
122
- text = text.force_encoding( Encoding::UTF_8 )
123
- logger.debug "text.encoding.name (after): #{text.encoding.name}"
124
-
125
- text_ary << text
126
- end
127
-
128
- ## note: need to pass in all fixtures at once (e.g as array) for @last_pos calc etc to work
129
- ## if multipe "files"/strings are used
130
- unless text_ary.empty?
131
- puts " importing/reading source..."
132
- # passing dummy include_path (not needed for reading from string)
133
- # fix: use/add proper api for reading from string e.g. read and read_file ?? etc.
134
- reader= GameReader.new( '/tmp' )
135
- ### fix: allow to pass in event (to avoid lookup)
136
- reader.read_fixtures_from_string( event.key, text_ary )
137
- end
138
- end
139
-
140
-
141
- def run
142
- # for now update all events (fixtures only) - not *.yml
143
-
144
- Event.all.each do |event|
145
- update_event( event )
146
- end
147
-
148
- end
149
-
150
- end # class Updater
151
-
152
- end # module SportDb
@@ -1,91 +0,0 @@
1
- # encoding: utf-8
2
-
3
- module SportDb
4
- module FixtureHelpers
5
-
6
-
7
- def find_record_comment!( line )
8
- # assume everything left after the last record marker,that is, ] is a record comment
9
-
10
- regex = /]([^\]]+?)$/ # NB: use non-greedy +?
11
-
12
- if line =~ regex
13
- value = $1.strip
14
- return nil if value.blank? # skip whitespaces only
15
-
16
- logger.debug " comment: >#{value}<"
17
-
18
- line.sub!( value, '[REC.COMMENT] ' )
19
- return value
20
- else
21
- return nil
22
- end
23
- end
24
-
25
-
26
- def find_record_timeline!( line )
27
-
28
- # +1 lap or +n laps
29
- regex_laps = /\s+\+\d{1,2}\s(lap|laps)\b/
30
-
31
- # 2:17:15.123
32
- regex_time = /\b\d{1,2}:\d{2}:\d{2}\.\d{1,3}\b/
33
-
34
- # +40.1 secs
35
- regex_secs = /\s+\+\d{1,3}\.\d{1,3}\s(secs)\b/ # NB: before \+ - boundry (\b) will not work
36
-
37
- # NB: $& contains the complete matched text
38
-
39
- if line =~ regex_laps
40
- value = $&.strip
41
- logger.debug " timeline.laps: >#{value}<"
42
-
43
- line.sub!( value, '[REC.TIMELINE.LAPS] ' ) # NB: add trailing space
44
- return value
45
- elsif line =~ regex_time
46
- value = $&.strip
47
- logger.debug " timeline.time: >#{value}<"
48
-
49
- line.sub!( value, '[REC.TIMELINE.TIME] ' ) # NB: add trailing space
50
- return value
51
- elsif line =~ regex_secs
52
- value = $&.strip
53
- logger.debug " timeline.secs: >#{value}<"
54
-
55
- line.sub!( value, '[REC.TIMELINE.SECS] ' ) # NB: add trailing space
56
- return value
57
- else
58
- return nil
59
- end
60
- end
61
-
62
- def find_record_laps!( line )
63
- # e.g. first free-standing number w/ one or two digits e.g. 7 or 28 etc.
64
- regex = /\b(\d{1,2})\b/
65
- if line =~ regex
66
- logger.debug " laps: >#{$1}<"
67
-
68
- line.sub!( regex, '[REC.LAPS] ' ) # NB: add trailing space
69
- return $1.to_i
70
- else
71
- return nil
72
- end
73
- end
74
-
75
- def find_record_leading_state!( line )
76
- # e.g. 1|2|3|etc or Ret - must start line
77
- regex = /^[ \t]*(\d{1,3}|Ret)[ \t]+/
78
- if line =~ regex
79
- value = $1.dup
80
- logger.debug " state: >#{value}<"
81
-
82
- line.sub!( regex, '[REC.STATE] ' ) # NB: add trailing space
83
- return value
84
- else
85
- return nil
86
- end
87
- end
88
-
89
-
90
- end # module FixtureHelpers
91
- end # module SportDb