class NbaSchedule

Access NBA team schedule data

Attributes

allGames[R]

@return [Navigator] Navigator All Schedule data @see GAME_F @see GAME_P

futureGames[R]

@return [Navigator] Navigator for Future Games @note (see SymbolDefaults::GAME_F) @see SymbolDefaults::GAME_F

game_list[R]
losses[R]
next_game[R]
pastGames[R]

Return Schedule info of Past Games @return [Navigator] Navigator for Past Games @note (see SymbolDefaults::GAME_P) @see SymbolDefaults::GAME_P

wins[R]
year[R]

Public Class Methods

new(args) click to toggle source

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

lastGame() click to toggle source

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
nextGame() click to toggle source

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
nextGameId() click to toggle source

@return [Integer] Game # of Next Game

# File lib/hoopscrape/NbaSchedule.rb, line 66
def nextGameId
  @next_game
end
nextTeamId() click to toggle source

@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

collectNodeSets(doc) click to toggle source

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
extract_boxscore_id(cell) click to toggle source
# 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
findSeasonType(indicator) click to toggle source

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
formatGameDate(month_day, year, game_time = '00:00:00') click to toggle source

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
futureGame(row, result) click to toggle source

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
getNokoDoc(args) click to toggle source

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
pastGame(row, result, season_type) click to toggle source

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
processSeason(schedule, tid, year1, seasontype, new_form) click to toggle source

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
saveGameResult(cell, result, txt) click to toggle source

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
saveHomeOpponent(cell, result, txt) click to toggle source

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
saveProcessedScheduleRow(tmp, game_date, season_type, new_form, game_in_past) click to toggle source

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
saveTV(cell, txt, result) click to toggle source

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
saveTeamRecord(result, season_type, text) click to toggle source

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
verifySeasonType(s_type, indicator) click to toggle source

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