Class: Footty::OpenfootballDataset

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

Constant Summary collapse

SOURCES =
{
  'world' => { '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

#end_date, #matches_for, #matches_within, #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)


93
94
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
# File 'lib/footty/openfootball.rb', line 93

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)


  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)


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

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 2025 or 2024/25 for now

                spec.index( '$year$') ? '2025' : '2024/25'
            end
  season
end

.leaguesObject

return built-in league keys



71
# File 'lib/footty/openfootball.rb', line 71

def self.leagues()  SOURCES.keys; end

Instance Method Details

#get!(url) ⇒ Object



150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
# File 'lib/footty/openfootball.rb', line 150

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



146
# File 'lib/footty/openfootball.rb', line 146

def league_name() @league_name; end

#matchesObject



145
# File 'lib/footty/openfootball.rb', line 145

def matches()     @matches; end

#openfootball_url(path, season:) ⇒ Object



134
135
136
137
138
139
140
141
142
# File 'lib/footty/openfootball.rb', line 134

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