Class: Footty::OpenfootballDataset

Inherits:
Dataset
  • Object
show all
Defined in:
lib/footty/dataset/openfootball.rb

Constant Summary collapse

SOURCES =
{
  'world' => { '2026' => [ 'worldcup/2026--usa/cup.txt',
                           'worldcup/2026--usa/cup_finals.txt'],
               '2022' => [ 'worldcup/2022--qatar/cup.txt',
                           'worldcup/2022--qatar/cup_finals.txt'],
               '2018' => [ 'worldcup/2018--russia/cup.txt',
                           'worldcup/2018--russia/cup_finals.txt']
             },
  'euro' =>  { '2024' => 'euro/2024--germany/euro.txt',
               '2021' => 'euro/2021--europe/euro.txt'
             },
  'de'    =>    'deutschland/$season$/1-bundesliga.txt',
  'de2'   =>   'deutschland/$season$/2-bundesliga2.txt',
  'de3'   =>   'deutschland/$season$/3-liga3.txt',
  'decup' =>   'deutschland/$season$/cup.txt',


  'en'   =>    'england/$season$/1-premierleague.txt',
  'en2'  =>    'england/$season$/2-championship.txt',
  ##  add alternate codes!!!
  ##   use  eflcup, facup - why? why not?
  'eneflcup'  =>  'england/$season$/eflcup.txt',
  'enfacup'   =>  'england/$season$/facup.txt',


  'es'    =>  'espana/$season$/1-liga.txt',
  'escup' =>  'espana/$season$/cup.txt',

  'it'=>    'italy/$season$/1-seriea.txt',

  'at'=>    'austria/$season$/1-bundesliga.txt',
  'at2'  =>   'austria/$season$/2-liga2.txt',
  'at3o' =>   'austria/$season$/3-regionalliga-ost.txt',
  'atcup' =>  'austria/$season$/cup.txt',

  'fr'=>    'europe/france/$season$_fr1.txt',
  'nl'=>    'europe/netherlands/$season$_nl1.txt',
  'be'=>    'europe/belgium/$season$_be1.txt',

  'champs'     => 'champions-league/$season$/cl.txt',
  'uefacl'    => 'champions-league/$season$/cl.txt',
  'uefael'    => 'champions-league/$season$/el.txt',
  'uefaconf'  => 'champions-league/$season$/conf.txt',


  'br'    => 'south-america/brazil/$year$_br1.txt',
  'ar'    => 'south-america/argentina/$year$_ar1.txt',
  'co'    => 'south-america/colombia/$year$_co1.txt',

  ## use a different code for copa libertadores? why? why not?
  'copa'  => 'south-america/copa-libertadores/$year$_copal.txt',

  'mx'    => 'world/north-america/mexico/$season$_mx1.txt',
  'mls'   => 'world/north-america/major-league-soccer/$year$_mls.txt',

  'concacafcl' => 'world/north-america/champions-league/$year$_concacafcl.txt',

  'eg'    => 'world/africa/egypt/$season$_eg1.txt',
  'ma'    => 'world/africa/morocco/$season$_ma1.txt',

  'au'    =>  'world/pacific/australia/$season$_au1.txt',
  'jp'    =>  'world/asia/japan/$year$_jp1.txt',
  'cn'    =>  'world/asia/china/$year$_cn1.txt',

}

Class Method Summary collapse

Instance Method Summary collapse

Methods inherited from Dataset

#_select_matches, #end_date, #past_matches, #query, #start_date, #todays_matches, #tomorrows_matches, #upcoming_matches, #weeks_matches, #yesterdays_matches

Constructor Details

#initialize(league:, season:) ⇒ OpenfootballDataset

Returns a new instance of OpenfootballDataset.

Raises:

  • (ArgumentError)


95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
# File 'lib/footty/dataset/openfootball.rb', line 95

def initialize( league:, season: )
  spec = SOURCES[ league.downcase ]

  urls = if spec.is_a?( Hash )  ## assume lookup by year
            spec[ season ]
          else  ## assume vanilla urls (no lookup by year)
            spec
          end
  raise ArgumentError, "no dataset (source) for league #{league} found"    if urls.nil?

  ## wrap single sources (strings) in array
  urls = urls.is_a?( Array ) ? urls : [urls]
  ## expand shortened url and fill-in template vars
  urls = urls.map { |url| openfootball_url( url, season: season ) }

  matches = []
  urls.each do |url|
                txt = get!( url )    ## use "memoized" / cached result
                parser = SportDb::QuickMatchReader.new( txt )
                matches += parser.parse
                ###  for multiple source file use latest name as "definitive"
                @league_name = parser.league_name
                ###  todo/fix - report errors
              end

  matches = matches.map {|match| match.as_json }  # convert to json

  ## note - sort by date/time
  ##  (assume stable sort; no reshuffle of matches if already sorted by date/time)


  ###
  ## note - convert date to date obj or nil !!!
  matches = matches.map do |match|
                             if match['date'] && match['date'].empty? == false
                                match['date'] = Date.strptime( match['date'], '%Y-%m-%d' )
                             else
                                match['date'] = nil
                             end

                             match
                        end


  matches = matches.sort do |l,r|
                 result =  l['date'] <=> r['date']
                 result =  l['time'] <=> r['time']    if result == 0 &&
                                                       (l['time'] && r['time'])
                 result
              end

  @matches = matches
end

Class Method Details

.latest_season(league:) ⇒ Object

auto-fill latest season

Raises:

  • (ArgumentError)


78
79
80
81
82
83
84
85
86
87
88
89
90
91
# File 'lib/footty/dataset/openfootball.rb', line 78

def self.latest_season( league: )
  spec = SOURCES[ league.downcase ]

  raise ArgumentError, "no dataset (source) for league #{league} found"    if spec.nil?

  ##  todo/fix - report error if no spec found
  season =  if spec.is_a?( Hash )  ## assume lookup by year
                spec.keys[0]
            else  ## assume vanilla urls (no lookup by year)
                ## default to 2026 or 2025/26 for now
                spec.index( '$year$') ? '2026' : '2025/26'
            end
  season
end

.leaguesObject

return built-in league keys



73
# File 'lib/footty/dataset/openfootball.rb', line 73

def self.leagues()  SOURCES.keys; end

Instance Method Details

#get!(url) ⇒ Object



167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
# File 'lib/footty/dataset/openfootball.rb', line 167

def get!( url )
    ##  use cached urls for 12h by default
    ##  if expired in cache (or not present) than get/fetch
   if Webcache.expired_in_12h?( url )
     response = Webget.text( url )

     if response.status.ok?
       response.text   # note - return text (utf-8)
     else
       ## dump headers
       response.headers.each do |key,value|
         puts "   #{key}:  #{value}"
       end
       puts "!! HTTP ERROR - #{response.status.code} #{response.status.message}"
       exit 1
     end
   else
     Webcache.read( url )
   end
end

#league_nameObject



163
# File 'lib/footty/dataset/openfootball.rb', line 163

def league_name() @league_name; end

#matchesObject



162
# File 'lib/footty/dataset/openfootball.rb', line 162

def matches()     @matches; end

#openfootball_url(path, season:) ⇒ Object



151
152
153
154
155
156
157
158
159
# File 'lib/footty/dataset/openfootball.rb', line 151

def openfootball_url( path, season: )
   repo, local_path = path.split( '/',  2)
   url = "https://raw.githubusercontent.com/openfootball/#{repo}/master/#{local_path}"
   ## check for template vars too
   season = Season( season )
   url = url.gsub( '$year$',   season.start_year.to_s )
   url = url.gsub( '$season$', season.to_path )
   url
end