nfl_data 0.0.10 → 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (59) hide show
  1. checksums.yaml +5 -5
  2. data/.envrc +7 -0
  3. data/.gitignore +3 -3
  4. data/.rspec +1 -0
  5. data/.standard.yml +2 -0
  6. data/.travis.yml +6 -0
  7. data/CHANGELOG.md +7 -0
  8. data/Gemfile +1 -1
  9. data/README.md +94 -21
  10. data/Rakefile +5 -6
  11. data/bin/console +1 -1
  12. data/bin/setup +8 -0
  13. data/lib/nfl_data.rb +10 -18
  14. data/lib/nfl_data/api/player.rb +8 -30
  15. data/lib/nfl_data/api/schedule.rb +19 -0
  16. data/lib/nfl_data/api/statline.rb +8 -23
  17. data/lib/nfl_data/models/game.rb +5 -0
  18. data/lib/nfl_data/models/player.rb +11 -19
  19. data/lib/nfl_data/models/schedule.rb +12 -0
  20. data/lib/nfl_data/models/statline.rb +18 -28
  21. data/lib/nfl_data/my_sports_feeds/client.rb +45 -0
  22. data/lib/nfl_data/my_sports_feeds/players_feed.rb +18 -0
  23. data/lib/nfl_data/my_sports_feeds/seasonal_games_feed.rb +22 -0
  24. data/lib/nfl_data/my_sports_feeds/weekly_player_gamelogs.rb +21 -0
  25. data/lib/nfl_data/parsers/player_parser.rb +21 -81
  26. data/lib/nfl_data/parsers/schedule_parser.rb +20 -0
  27. data/lib/nfl_data/parsers/statline_parser.rb +27 -76
  28. data/lib/nfl_data/version.rb +1 -1
  29. data/nfl_data.gemspec +23 -21
  30. data/spec/api/player_spec.rb +24 -0
  31. data/spec/api/schedule_spec.rb +20 -0
  32. data/spec/api/statline_spec.rb +31 -0
  33. data/spec/models/game_spec.rb +15 -0
  34. data/spec/models/player_spec.rb +42 -0
  35. data/spec/models/schedule_spec.rb +17 -0
  36. data/spec/models/statline_spec.rb +63 -0
  37. data/spec/my_sports_feeds/client_spec.rb +17 -0
  38. data/spec/my_sports_feeds/players_feed_spec.rb +49 -0
  39. data/spec/my_sports_feeds/seasonal_games_feed_spec.rb +41 -0
  40. data/spec/my_sports_feeds/weekly_player_gamelogs_spec.rb +144 -0
  41. data/spec/parsers/player_parser_spec.rb +63 -0
  42. data/spec/parsers/schedule_parser_spec.rb +41 -0
  43. data/spec/parsers/statline_parser_spec.rb +68 -0
  44. data/spec/spec_helper.rb +55 -0
  45. metadata +107 -45
  46. data/lib/nfl_data/api/team.rb +0 -26
  47. data/lib/nfl_data/models/team.rb +0 -39
  48. data/lib/nfl_data/parsers/parser_helper.rb +0 -6
  49. data/lib/nfl_data/parsers/team_parser.rb +0 -91
  50. data/test/nfl_data/api/player_test.rb +0 -25
  51. data/test/nfl_data/api/statline_test.rb +0 -21
  52. data/test/nfl_data/api/team_test.rb +0 -13
  53. data/test/nfl_data/models/player_test.rb +0 -75
  54. data/test/nfl_data/models/statline_test.rb +0 -126
  55. data/test/nfl_data/models/team_test.rb +0 -45
  56. data/test/nfl_data/parsers/player_parser_test.rb +0 -80
  57. data/test/nfl_data/parsers/statline_parser_test.rb +0 -35
  58. data/test/nfl_data/parsers/team_parser_test.rb +0 -41
  59. data/test/test_helper.rb +0 -12
@@ -1,30 +1,20 @@
1
1
  module NflData
2
-
3
- class Statline
4
- attr_accessor :week, :year, :rush_atts, :rush_yards, :rush_tds, :fumbles,
5
- :pass_comp, :pass_att, :pass_yards, :pass_tds, :ints, :qb_rating, :receptions,
6
- :rec_yards, :rec_tds, :nfl_player_id, :sacks
7
-
8
- def to_hash
9
- {
10
- nfl_player_id: nfl_player_id,
11
- week: week,
12
- year: year,
13
- rush_atts: rush_atts,
14
- rush_yards: rush_yards,
15
- rush_tds: rush_tds,
16
- fumbles: fumbles,
17
- pass_comp: pass_comp,
18
- pass_att: pass_att,
19
- pass_yards: pass_yards,
20
- pass_tds: pass_tds,
21
- ints: ints,
22
- qb_rating: qb_rating,
23
- receptions: receptions,
24
- rec_yards: rec_yards,
25
- rec_tds: rec_tds
26
- }
27
- end
28
- end
29
-
2
+ Statline = Struct.new(
3
+ :rush_atts,
4
+ :rush_yards,
5
+ :rush_tds,
6
+ :fumbles,
7
+ :pass_comp,
8
+ :pass_att,
9
+ :pass_yards,
10
+ :pass_tds,
11
+ :ints,
12
+ :qb_rating,
13
+ :receptions,
14
+ :rec_yards,
15
+ :rec_tds,
16
+ :msf_game_id,
17
+ :msf_player_id,
18
+ keyword_init: true
19
+ )
30
20
  end
@@ -0,0 +1,45 @@
1
+ # frozen_string_literal: true
2
+
3
+ module NflData
4
+ module MySportsFeeds
5
+ class Client
6
+ attr_reader :base_url, :api_key, :api_host, :api_version, :format
7
+
8
+ def initialize(
9
+ api_host: ENV.fetch("MYSPORTSFEEDS_API_HOST"),
10
+ api_key: ENV.fetch("MYSPORTSFEEDS_API_KEY"),
11
+ api_version: ENV.fetch("MYSPORTSFEEDS_API_VERSION")
12
+ )
13
+ @api_host = api_host
14
+ @api_key = api_key
15
+ @api_version = api_version
16
+ @format = "json"
17
+ @base_url = "#{@api_host}/#{@api_version}/pull/nfl/"
18
+ end
19
+
20
+ def get(endpoint:, params: {})
21
+ request(method: :get, endpoint: endpoint, params: params)
22
+ end
23
+
24
+ private
25
+
26
+ def request(method:, endpoint:, params:)
27
+ request = Typhoeus::Request.new(
28
+ "#{base_url}#{endpoint}.#{format}",
29
+ method: method,
30
+ params: params,
31
+ accept_encoding: "gzip",
32
+ userpwd: "#{api_key}:MYSPORTSFEEDS"
33
+ )
34
+
35
+ # request.on_complete do |response|
36
+ # if response.success?
37
+ # end
38
+ # end
39
+
40
+ response = request.run
41
+ JSON.parse(response.body)
42
+ end
43
+ end
44
+ end
45
+ end
@@ -0,0 +1,18 @@
1
+ # frozen_string_literal: true
2
+
3
+ module NflData
4
+ module MySportsFeeds
5
+ class PlayersFeed
6
+ attr_reader :client
7
+
8
+ def initialize(client: MySportsFeeds::Client.new)
9
+ @client = client
10
+ end
11
+
12
+ def feed(position: nil)
13
+ params = {position: position}
14
+ client.get(endpoint: "players", params: params)["players"]
15
+ end
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,22 @@
1
+ # frozen_string_literal: true
2
+
3
+ module NflData
4
+ module MySportsFeeds
5
+ class SeasonalGamesFeed
6
+ attr_reader :client
7
+
8
+ def initialize(client: MySportsFeeds::Client.new)
9
+ @client = client
10
+ end
11
+
12
+ def feed(season_start_year:)
13
+ response = client.get(endpoint: "#{season_slug(season_start_year)}/games")
14
+ response["games"].map { |data| data["schedule"] }
15
+ end
16
+
17
+ def season_slug(year)
18
+ "#{year}-#{year + 1}-regular"
19
+ end
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,21 @@
1
+ # frozen_string_literal: true
2
+
3
+ module NflData
4
+ module MySportsFeeds
5
+ class WeeklyPlayerGamelogs
6
+ attr_reader :client
7
+
8
+ def initialize(client: MySportsFeeds::Client.new)
9
+ @client = client
10
+ end
11
+
12
+ def feed(season_start_year:, week:)
13
+ client.get(endpoint: "#{season_slug(season_start_year)}/week/#{week}/player_gamelogs")["gamelogs"]
14
+ end
15
+
16
+ def season_slug(year)
17
+ "#{year}-#{year + 1}-regular"
18
+ end
19
+ end
20
+ end
21
+ end
@@ -1,88 +1,28 @@
1
- module NflData
2
- class PlayerParser
3
- include ParserHelper
4
-
5
- attr_reader :base_url
6
-
7
- def initialize
8
- @base_url = "http://www.nfl.com/players/search?category=position&conferenceAbbr=null&playerType=current&conference=ALL&filter="
9
- end
1
+ # frozen_string_literal: true
10
2
 
11
- def get_by_position(position)
12
- case position
13
- when :quarterbacks
14
- { position => get('quarterback') }
15
- when :runningbacks
16
- { position => get('runningback') }
17
- when :wide_receivers
18
- { position => get('widereceiver') }
19
- when :tight_ends
20
- { position => get('tightend') }
21
- when :all
22
- {
23
- quarterbacks: get('quarterback'),
24
- runningbacks: get('runningback'),
25
- wide_receivers: get('widereceiver'),
26
- tight_ends: get('tightend')
27
- }
28
- end
29
- end
30
-
31
- private
32
-
33
- def get(position)
34
- baseurl = @base_url + position
35
- url = baseurl
36
- returnVal = []
37
- page_num = 1
38
-
39
- count = 100
40
-
41
- loop do
42
- page_num += 1
43
- players_found = update_or_create_players(url)
44
- returnVal.push(players_found[1])
45
- break if players_found[0] == 0
46
- url = baseurl + '&d-447263-p='
47
- url += page_num.to_s
3
+ module NflData
4
+ module Parsers
5
+ class PlayerParser
6
+ def parse(player_data:)
7
+ player_data.map { |data| data["player"] }.map do |data|
8
+ init_player(data)
9
+ end
48
10
  end
49
11
 
50
- returnVal.flatten.map{ |player| player.to_hash }
51
- end
52
-
53
- def update_or_create_players(url)
54
- # puts "Pulling from url = #{url}"
55
- doc = open(url) { |f| Nokogiri(f) }
56
-
57
- #NFL.com stores players in 2 types of rows. Class = Odd or Even. This pulls them all.
58
- odds = doc.search("tr.odd")
59
- evens = doc.search("tr.even")
60
-
61
- all = odds + evens
62
-
63
- players = all.map do |p|
64
- player = Player.new
65
- elements = p.search("td")
66
- player.position = elements[0].inner_text.strip
67
- player.number = elements[1].inner_text.strip
68
- name = elements[2].inner_text.strip
69
- player.status = elements[3].inner_text.strip
70
- player.team = make_jacksonville_abbreviation_consistent(elements[12].inner_text.strip)
71
-
72
- #Get NFL.com Unique player id
73
- player.nfl_player_id = elements[2].to_s.split('/')[3]
74
-
75
- names = name.split(',')
76
-
77
- player.first_name = names[1].strip
78
- player.last_name = names[0].strip
79
-
80
- player.full_name = [player.first_name, player.last_name].join(' ')
81
- player
12
+ private
13
+
14
+ def init_player(data)
15
+ Player.new(
16
+ first_name: data["firstName"],
17
+ last_name: data["lastName"],
18
+ full_name: "#{data["firstName"]} #{data["lastName"]}".chomp,
19
+ position: data["primaryPosition"],
20
+ number: data["jerseyNumber"],
21
+ team: data.dig("currentTeam", "abbreviation").to_s,
22
+ msf_player_id: data["id"],
23
+ image_source: data["officialImageSrc"].to_s
24
+ )
82
25
  end
83
-
84
- [players.count, players]
85
26
  end
86
-
87
27
  end
88
28
  end
@@ -0,0 +1,20 @@
1
+ module NflData
2
+ module Parsers
3
+ class ScheduleParser
4
+ def parse(schedule_data:)
5
+ Schedule.new(games: schedule_data.map { |data| init_game(data) })
6
+ end
7
+
8
+ private
9
+
10
+ def init_game(data)
11
+ Game.new(
12
+ week: data["week"],
13
+ home_team: data.dig("homeTeam", "abbreviation"),
14
+ away_team: data.dig("awayTeam", "abbreviation"),
15
+ start_time: data["startTime"]
16
+ )
17
+ end
18
+ end
19
+ end
20
+ end
@@ -1,83 +1,34 @@
1
- module NflData
2
- class StatlineParser
3
-
4
- def initialize
5
- end
6
-
7
- def get(week, year, stat_type)
8
- case stat_type
9
- when :passing
10
- grab_week(week, year, 'Passing')
11
- when :rushing
12
- grab_week(week, year, 'Rushing')
13
- when :receiving
14
- grab_week(week, year, 'Receiving')
15
- end
16
- end
1
+ # frozen_string_literal: true
17
2
 
18
- private
19
-
20
- def get_player_id_from_profile_url(element)
21
- old_url = "http://nfl.com" + element.search('a').first.attributes['href'].value
22
- new_url = ""
23
-
24
- begin
25
- open(old_url) do |resp|
26
- new_url = resp.base_uri.to_s
3
+ module NflData
4
+ module Parsers
5
+ class StatlineParser
6
+ def parse(statline_data:)
7
+ statline_data.map do |data|
8
+ init_statline(data)
27
9
  end
28
- rescue
29
- return nil
30
10
  end
31
11
 
32
- new_url.gsub("http://www.nfl.com","").to_s.split('/')[3]
33
- end
34
-
35
- def grab_week(weeknum, year, stat_type)
36
- baseUrl = "http://www.nfl.com/stats/weeklyleaders?type=REG"
37
- weekUrl = "&week="
38
- seasonUrl = "&season=" + year.to_s
39
- catUrl = "&showCategory="
40
-
41
- url = baseUrl + weekUrl + weeknum.to_s + seasonUrl + catUrl + stat_type
42
-
43
- doc = open(url) { |f| Nokogiri(f) }
44
-
45
- odds = doc.search("tr.odd")
46
- evens = doc.search("tr.even")
47
-
48
- all = odds + evens
49
-
50
- all.map do |player_row|
51
- elements = player_row.search("td")
52
-
53
- statline = Statline.new
54
-
55
- statline.nfl_player_id = get_player_id_from_profile_url(elements[0])
56
- statline.week = weeknum
57
- statline.year = year
58
-
59
- if (stat_type == 'Rushing')
60
- statline.rush_atts = elements[4].inner_text.strip
61
- statline.rush_yards = elements[5].inner_text.strip
62
- statline.rush_tds = elements[7].inner_text.strip
63
- statline.fumbles = elements[8].inner_text.strip
64
- elsif (stat_type == 'Passing')
65
- statline.pass_comp = elements[4].inner_text.strip
66
- statline.pass_att = elements[5].inner_text.strip
67
- statline.pass_yards = elements[6].inner_text.strip
68
- statline.pass_tds = elements[7].inner_text.strip
69
- statline.ints = elements[8].inner_text.strip
70
- statline.sacks = elements[9].inner_text.strip
71
- statline.qb_rating = elements[11].inner_text.strip
72
- statline.fumbles = elements [10].inner_text.strip
73
- elsif (stat_type == 'Receiving')
74
- statline.receptions = elements[4].inner_text.strip
75
- statline.rec_yards = elements[5].inner_text.strip
76
- statline.rec_tds = elements[7].inner_text.strip
77
- statline.fumbles = elements[8].inner_text.strip
78
- end
79
-
80
- statline.to_hash
12
+ private
13
+
14
+ def init_statline(data)
15
+ Statline.new(
16
+ rush_atts: data.dig("stats", "rushing", "rushAttempts") || 0,
17
+ rush_yards: data.dig("stats", "rushing", "rushYards") || 0,
18
+ rush_tds: data.dig("stats", "rushing", "rushTD") || 0,
19
+ fumbles: data.dig("stats", "fumbles", "fumbles") || 0,
20
+ pass_comp: data.dig("stats", "passing", "passCompletions") || 0,
21
+ pass_att: data.dig("stats", "passing", "passAttempts") || 0,
22
+ pass_yards: data.dig("stats", "passing", "passYards") || 0,
23
+ pass_tds: data.dig("stats", "passing", "passTD") || 0,
24
+ ints: data.dig("stats", "interceptions", "interceptions") || 0,
25
+ qb_rating: data.dig("stats", "passing", "qbRating") || 0,
26
+ receptions: data.dig("stats", "receiving", "receptions") || 0,
27
+ rec_yards: data.dig("stats", "receiving", "recYards") || 0,
28
+ rec_tds: data.dig("stats", "receiving", "recTD") || 0,
29
+ msf_game_id: data.dig("game", "id"),
30
+ msf_player_id: data.dig("player", "id")
31
+ )
81
32
  end
82
33
  end
83
34
  end
@@ -1,3 +1,3 @@
1
1
  module NflData
2
- VERSION = '0.0.10'
2
+ VERSION = "0.1.0"
3
3
  end
@@ -1,29 +1,31 @@
1
- # coding: utf-8
2
- lib = File.expand_path('../lib', __FILE__)
1
+ lib = File.expand_path("../lib", __FILE__)
3
2
  $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
3
 
5
- require 'nfl_data/version'
4
+ require "nfl_data/version"
6
5
 
7
6
  Gem::Specification.new do |spec|
8
- spec.name = 'nfl_data'
9
- spec.version = NflData::VERSION
10
- spec.authors = ['thetizzo']
11
- spec.email = ['j.m.taylor1@gmail.com']
12
- spec.homepage = 'https://github.com/thetizzo/nfl_data'
13
- spec.license = 'MIT'
14
- spec.summary = %q{Parse NFL data like a boss}
15
- spec.description = %q{Parse NFL data like a boss}
7
+ spec.name = "nfl_data"
8
+ spec.version = NflData::VERSION
9
+ spec.authors = ["thetizzo"]
10
+ spec.email = ["j.m.taylor1@gmail.com"]
11
+ spec.homepage = "https://github.com/thetizzo/nfl_data"
12
+ spec.license = "MIT"
13
+ spec.summary = "Parse NFL data like a boss"
14
+ spec.description = "Parse NFL data like a boss"
16
15
 
17
- spec.files = `git ls-files -z`.split("\x0")
18
- spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
19
- spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
20
- spec.require_paths = ['lib']
16
+ spec.files = `git ls-files -z`.split("\x0")
17
+ spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
18
+ spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
19
+ spec.require_paths = ["lib"]
21
20
 
22
- spec.add_development_dependency 'bundler', '~> 1.6'
23
- spec.add_development_dependency 'rake'
24
- spec.add_development_dependency 'minitest', '~> 5.4.1'
25
- spec.add_development_dependency 'vcr', '~> 2.9.3'
26
- spec.add_development_dependency 'webmock', '~> 1.19.0'
21
+ spec.add_development_dependency "rake", "~> 13.0"
22
+ spec.add_development_dependency "rspec", "~> 3.9"
23
+ spec.add_development_dependency "rspec-resembles_json_matchers", "~> 0.9"
24
+ spec.add_development_dependency "vcr", "~> 4.0.0"
25
+ spec.add_development_dependency "webmock", "~> 3.8"
26
+ spec.add_development_dependency "standard", "~> 0.1"
27
27
 
28
- spec.add_dependency 'nokogiri', '~> 1.6'
28
+ spec.add_dependency "nokogiri", "~> 1.10"
29
+ spec.add_dependency "typhoeus", "~> 1.4"
30
+ spec.add_dependency "zeitwerk", "~> 2.4"
29
31
  end