class NbaSchedule
Access NBA team schedule data
Attributes
@return [Navigator] Navigator
All Schedule data @see GAME_F @see GAME_P
@return [Navigator] Navigator
for Future Games @note (see SymbolDefaults::GAME_F) @see SymbolDefaults::GAME_F
Return Schedule info of Past Games @return [Navigator] Navigator
for Past Games @note (see SymbolDefaults::GAME_P) @see SymbolDefaults::GAME_P
Public Class Methods
Read Schedule data for a given Team @param team_id [String] Team ID @param file [String] HTML Test Data @param season_type [Integer] Season Type @param year [Integer] Ending Year of Season @note
Season Types: 1-Preseason; 2-Regular Season; 3-Playoffs
@example
test = NbaSchedule.new('', file: 'test/data/testData.html') pre = NbaSchedule.new('UTA', s_type: 1) playoffs = NbaSchedule.new('GSW', s_type: 3)
# File lib/hoopscrape/NbaSchedule.rb, line 20 def initialize(args) doc, seasontype = getNokoDoc(args) return if doc.nil? @game_list = [] # Processed Schedule Data @next_game = 0 # Cursor to start of Future Games schedule, @year, indicator, tid = collectNodeSets(doc) season_valid = verifySeasonType(seasontype, indicator) seasontype = findSeasonType(indicator) if seasontype.to_i.eql?(0) @wins = @losses = 0 processSeason(schedule, tid, @year, seasontype, args[:format]) if season_valid && !seasontype.eql?(0) @allGames = Navigator.new(@game_list) @futureGames = Navigator.new(@game_list[@next_game, game_list.size]) @pastGames = Navigator.new(@game_list[0, @next_game]) @game_list = nil @year = "#{@year}-#{(@year + 1).to_s[2, 4]}" end
Public Instance Methods
Returns Schedule info of last completed game @return [Object] Past Schedule Row (Array/Hash/Struct) @note (see pastGames
) @example
lastGame #=> ['UTA', '12', '00:00:00', 'false', 'Nov 20', 'false', 'DAL', 'false', '93', '102', '400828071', '6', '6', '2015-11-20 00:00:00', '2']
@see SymbolDefaults::GAME_P
# File lib/hoopscrape/NbaSchedule.rb, line 61 def lastGame allGames[][@next_game - 1] end
Returns Schedule info of next game @return [[Object]] Future Schedule Row (Array/Hash/Struct) @note (see futureGames
) @example
nextGame #=> ['UTA', '13', 'Nov 23', 'true', 'OKC', '9:00 PM ET', 'false', '2015-11-23 21:00:00', '2']
@see GAME_F
# File lib/hoopscrape/NbaSchedule.rb, line 51 def nextGame allGames[][@next_game] unless allGames[].nil? end
@return [Integer] Game # of Next Game
# File lib/hoopscrape/NbaSchedule.rb, line 66 def nextGameId @next_game end
@return [String] Team ID of next opponent @example
nextTeamId #=> "OKC"
# File lib/hoopscrape/NbaSchedule.rb, line 73 def nextTeamId nextGame[4] if nextGame end
Private Instance Methods
Extract NodeSets
# File lib/hoopscrape/NbaSchedule.rb, line 98 def collectNodeSets(doc) schedule = doc.xpath('//div/div/table/tr') # Schedule Rows year = doc.xpath('//div[@id=\'my-teams-table\']/div/div/div/h1').text.split('-')[1].strip.to_i # Season Starting Year season = doc.xpath("//tr[@class='stathead']").text.split[1].downcase # preseason/regular/postseason tid = getTid(doc.title.split(/\d{4}/)[0].strip).upcase [schedule, year, season, tid] end
# File lib/hoopscrape/NbaSchedule.rb, line 216 def extract_boxscore_id(cell) return 0 if cell.text.include? 'TBA' boxscore_id = cell.children.children.children[1].attributes['href'] return 0 if boxscore_id.nil? return boxscore_id.text.split('=')[1] if boxscore_id.text.include?('recap?id=') boxscore_id.text.split('/').last end
Determine season type from document data
# File lib/hoopscrape/NbaSchedule.rb, line 117 def findSeasonType(indicator) # Determine season type return 1 if indicator.include?('pre') return 2 if indicator.include?('regular') return 3 if indicator.include?('post') nil end
Adjust and format dates
# File lib/hoopscrape/NbaSchedule.rb, line 253 def formatGameDate(month_day, year, game_time = '00:00:00') year += 1 unless %w[Oct Nov Dec].include?(month_day.split[0]) d = DateTime.parse(game_time + ' , ' + month_day + ',' + year.to_s) d.strftime('%Y-%m-%d %H:%M:%S') # Game DateTime String end
Process Future Game Row
# File lib/hoopscrape/NbaSchedule.rb, line 173 def futureGame(row, result) row.children[0, 4].each_with_index do |cell, cnt| txt = cell.text.strip if cnt.zero? # Game Date result << txt.split(',')[1].strip elsif cnt == 1 # Home/Away, Opp tid saveHomeOpponent(cell, result, txt) elsif cnt == 2 # Game Time result << txt + ' ET' elsif cnt == 3 # TV saveTV(cell, txt, result) end end # Game Date, Game Time [result[2], result[5]] end
Return Nokogiri XML Document
# File lib/hoopscrape/NbaSchedule.rb, line 91 def getNokoDoc(args) return Nokogiri::HTML(open(args[:file])), args[:season_type] if args[:file] # Use File url = formatTeamUrl(args[:team_id], teamScheduleUrl(args[:season_type], args[:year])) [Nokogiri::HTML(open(url)), args[:season_type]] # Use Live Data end
Process Past Game Row
# File lib/hoopscrape/NbaSchedule.rb, line 155 def pastGame(row, result, season_type) row.children[0, 4].each_with_index do |cell, cnt| txt = cell.text.chomp if cnt.zero? # Game Date result << txt.split(',')[1].strip elsif cnt == 1 # Home Game? and Opponent ID saveHomeOpponent(cell, result, txt) elsif cnt == 2 # Game Result saveGameResult(cell, result, txt) else # Team Record saveTeamRecord(result, season_type, txt) end end # Game Date result[2] end
Process Table of Schedule Data
# File lib/hoopscrape/NbaSchedule.rb, line 126 def processSeason(schedule, tid, year1, seasontype, new_form) seasontype = seasontype.to_i game_id = 0 # 82-game counter # Process Schedule lines schedule.each do |row| game_date = '' game_time = '' if ('a'..'z').cover?(row.text[1]) # => Non-Header Row tmp = [tid, (game_id += 1).to_s] # TeamID, GameID if row.children.size == 3 # => Postponed Game game_id -= 1 next elsif row.children[2].text.include?(':') # => Future Game game_date, game_time = futureGame(row, tmp) game_in_past = false else # => Past Game @next_game = game_id game_time = '00:00:00' # Game Time (Not shown for past games) game_date = pastGame(row, tmp, seasontype) game_in_past = true end end saveProcessedScheduleRow(tmp, formatGameDate(game_date, year1, game_time), seasontype, new_form, game_in_past) unless tmp.nil? end end
Store Game Result Win?, Team Score, Opponent Score, Boxscore ID
# File lib/hoopscrape/NbaSchedule.rb, line 204 def saveGameResult(cell, result, txt) win = (txt[0, 1].include?('W') ? true : false) final_score = txt[1, txt.length].gsub(/\s?\d?OT/, '') if win team_score, opp_score = final_score.split('-') else opp_score, team_score = final_score.split('-') end box_id = extract_boxscore_id(cell) result << win.to_s << team_score.to_s << opp_score.to_s << box_id # Win?, Team Score, Opponent Score, Boxcore ID end
Store Home? and Opponent ID
# File lib/hoopscrape/NbaSchedule.rb, line 191 def saveHomeOpponent(cell, result, txt) result << (!txt[0, 1].include?('@')).to_s # Home Game? x0 = cell.children.children.children[1].attributes['href'] result << if x0.nil? # Non-NBA Team cell.children.children.children[1].text.strip else # NBA Team getTid(x0.text.split('/')[-1].split('-').join(' ')) # Opponent ID end end
Store Processed Schedule Row
# File lib/hoopscrape/NbaSchedule.rb, line 245 def saveProcessedScheduleRow(tmp, game_date, season_type, new_form, game_in_past) tmp << game_date # Game DateTime tmp << season_type.to_s # Season Type @game_list << tmp if new_form.nil? # Save processed Array @game_list += tmp.send(new_form, game_in_past ? S_GAME_P : S_GAME_F) unless new_form.nil? # Conversion end
Store TV?
# File lib/hoopscrape/NbaSchedule.rb, line 239 def saveTV(cell, txt, result) # Network image, link or name? result << (%w[a img].include?(cell.children[0].node_name) || txt.size > 1).to_s end
Store Team Record Wins, Losses
# File lib/hoopscrape/NbaSchedule.rb, line 226 def saveTeamRecord(result, season_type, text) if season_type == 3 # Team Record Playoffs result[5].eql?('true') ? @wins += 1 : @losses += 1 result << @wins.to_s << @losses.to_s else # Team Record Pre/Regular wins, losses = text.split('-') @wins = wins.to_i @losses = losses.to_i result << wins << losses end end
Ensure requested season type is what is being processed
# File lib/hoopscrape/NbaSchedule.rb, line 107 def verifySeasonType(s_type, indicator) # If season type is provided, verify case s_type when 1, 2, 3 return s_type.eql?(findSeasonType(indicator)) end true end