nba 0.0.3 → 0.1.1
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.
- checksums.yaml +4 -4
- data/.travis.yml +0 -5
- data/README.md +31 -18
- data/Rakefile +1 -0
- data/bin/nba +7 -0
- data/lib/faraday_middleware/scrape_game.rb +14 -2
- data/lib/nba.rb +1 -0
- data/lib/nba/cli.rb +35 -0
- data/lib/nba/game.rb +22 -6
- data/lib/nba/player.rb +10 -6
- data/lib/nba/team.rb +95 -63
- data/lib/nba/version.rb +1 -1
- data/nba.gemspec +2 -1
- data/spec/fixtures/games.html +785 -0
- data/spec/fixtures/teams.json +16529 -0
- data/spec/game_spec.rb +40 -0
- data/spec/spec_helper.rb +1 -1
- data/spec/team_spec.rb +93 -0
- metadata +29 -6
- data/spec/nba_spec.rb +0 -73
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: b953637ba9292b6414aec1db167b451df894d354
|
4
|
+
data.tar.gz: 4d7ba14450b621e09958d41009d7e883a04ab6fb
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: dc1baeadf0c937313ac2053e5c53758ee69f30713d6f772b5818ef673855275a20720452d573c21adb7ca04ac9d470253e54ba73a3f26a4d32e6828fa642fa35
|
7
|
+
data.tar.gz: e8a6da21617c53615298400d32ef93f01633933c1ed5fbe4709c42358d9501ff31003a314b3b16941e71fe9ab84cf82cd90abdcf866959090e78c6fb66408cc6
|
data/.travis.yml
CHANGED
@@ -6,17 +6,12 @@ before_install:
|
|
6
6
|
bundler_args: --without development
|
7
7
|
language: ruby
|
8
8
|
rvm:
|
9
|
-
- 1.8.7
|
10
|
-
- 1.9.2
|
11
9
|
- 1.9.3
|
12
10
|
- 2.0.0
|
13
11
|
- 2.1.0
|
14
|
-
- rbx
|
15
12
|
- ruby-head
|
16
13
|
matrix:
|
17
14
|
include:
|
18
|
-
- rvm: jruby-18mode
|
19
|
-
env: JRUBY_OPTS="$JRUBY_OPTS --debug"
|
20
15
|
- rvm: jruby-19mode
|
21
16
|
env: JRUBY_OPTS="$JRUBY_OPTS --debug"
|
22
17
|
- rvm: jruby-head
|
data/README.md
CHANGED
@@ -17,6 +17,36 @@ Insipred by [@sferik][sferik]'s [MLB.rb][mlb].
|
|
17
17
|
gem install nba
|
18
18
|
|
19
19
|
## Usage Examples
|
20
|
+
You could use `nba` command-line tool directly in your terminal.
|
21
|
+
|
22
|
+
$ nba games --date=20140102
|
23
|
+
Final/OT - Cavaliers 87 : 81 Magic
|
24
|
+
Final - Heat 114 : 123 Warriors
|
25
|
+
Final - Bulls 94 : 82 Celtics
|
26
|
+
Final - Thunder 93 : 95 Nets
|
27
|
+
Final - Spurs 101 : 105 Knicks
|
28
|
+
Final - Suns 91 : 99 Grizzlies
|
29
|
+
Final - Jazz 96 : 87 Bucks
|
30
|
+
Final - Trail Blazers 134 : 104 Bobcats
|
31
|
+
Final - Kings 104 : 113 76ers
|
32
|
+
$ nba teams --name 'Lakers'
|
33
|
+
Name: Los Angeles Lakers
|
34
|
+
Founded: 1947
|
35
|
+
Conference: Western Conference
|
36
|
+
Division: Pacific Division
|
37
|
+
Coach: Mike D'Antoni
|
38
|
+
Championships: 2010 NBA Finals, 2009 NBA Finals
|
39
|
+
2002 NBA Finals, 2001 NBA Finals
|
40
|
+
2000 NBA Finals, 1988 NBA Finals
|
41
|
+
1987 NBA Finals, 1985 NBA Finals
|
42
|
+
1982 NBA Finals, 1980 NBA Finals
|
43
|
+
1972 NBA Finals, 1954 NBA Finals
|
44
|
+
1953 NBA Finals, 1952 NBA Finals
|
45
|
+
1950 NBA Finals, 1949 BAA Finals
|
46
|
+
1948 NBL Finals
|
47
|
+
|
48
|
+
Or you could use it in `irb`, which is an Interactive Ruby Shell
|
49
|
+
|
20
50
|
$ irb
|
21
51
|
>> require 'nba'
|
22
52
|
>> NBA::Game.all '20140102'
|
@@ -39,30 +69,13 @@ Insipred by [@sferik][sferik]'s [MLB.rb][mlb].
|
|
39
69
|
This library aims to support and is [tested against][travis] the following Ruby
|
40
70
|
implementations:
|
41
71
|
|
42
|
-
* Ruby 1.8.7
|
43
|
-
* Ruby 1.9.2
|
44
72
|
* Ruby 1.9.3
|
45
73
|
* Ruby 2.0.0
|
46
74
|
* Ruby 2.1.0
|
47
|
-
* [Rubinius][]
|
48
75
|
* [JRuby][]
|
49
76
|
|
50
|
-
[rubinius]: http://rubini.us/
|
51
77
|
[jruby]: http://jruby.org/
|
52
78
|
|
53
|
-
If something doesn't work on one of these interpreters, it's a bug.
|
54
|
-
|
55
|
-
This library may inadvertently work (or seem to work) on other Ruby
|
56
|
-
implementations, however support will only be provided for the versions listed
|
57
|
-
above.
|
58
|
-
|
59
|
-
If you would like this library to support another Ruby version, you may
|
60
|
-
volunteer to be a maintainer. Being a maintainer entails making sure all tests
|
61
|
-
run and pass on that implementation. When something breaks on your
|
62
|
-
implementation, you will be responsible for providing patches in a timely
|
63
|
-
fashion. If critical issues for a particular implementation exist at the time
|
64
|
-
of a major release, support for that Ruby version may be dropped.
|
65
|
-
|
66
79
|
## Colophon
|
67
80
|
NBA was built with the following tools:
|
68
81
|
|
@@ -86,7 +99,7 @@ And, special thanks to [@sfeirk][sferik]!
|
|
86
99
|
|
87
100
|
## Contributing
|
88
101
|
|
89
|
-
1. Fork it
|
102
|
+
1. [Fork it](http://github.com/larrylv/nba/fork)
|
90
103
|
2. Create your feature branch (`git checkout -b my-new-feature`)
|
91
104
|
3. Commit your changes (`git commit -am 'Add some feature'`)
|
92
105
|
4. Push to the branch (`git push origin my-new-feature`)
|
data/Rakefile
CHANGED
data/bin/nba
ADDED
@@ -7,12 +7,24 @@ module FaradayMiddleware
|
|
7
7
|
doc = Nokogiri::HTML.parse body
|
8
8
|
doc.css('.score-row .mod-content').inject([]) do |results, game_node|
|
9
9
|
home_team_node = game_node.css('.home').first
|
10
|
-
home_team = home_team_node.css('p.team-name').first.search('a').first.content
|
11
10
|
home_score = home_team_node.css('.finalScore').first.content
|
11
|
+
home_team_name_node = home_team_node.css('p.team-name').first
|
12
|
+
begin
|
13
|
+
home_team = home_team_name_node.search('a').first.content
|
14
|
+
rescue
|
15
|
+
# some teams may change their name, so the old team has no links.
|
16
|
+
home_team = home_team_name_node.search('span').first.content
|
17
|
+
end
|
12
18
|
|
13
19
|
away_team_node = game_node.css('.away').first
|
14
|
-
away_team = away_team_node.css('p.team-name').first.search('a').first.content
|
15
20
|
away_score = away_team_node.css('.finalScore').first.content
|
21
|
+
away_team_name_node = away_team_node.css('p.team-name').first
|
22
|
+
begin
|
23
|
+
away_team = away_team_name_node.search('a').first.content
|
24
|
+
rescue
|
25
|
+
# some teams may change their name, so the old team has no links.
|
26
|
+
away_team = away_team_name_node.search('span').first.content
|
27
|
+
end
|
16
28
|
|
17
29
|
status = game_node.css('.game-status').first.search('p').first.content
|
18
30
|
|
data/lib/nba.rb
CHANGED
data/lib/nba/cli.rb
ADDED
@@ -0,0 +1,35 @@
|
|
1
|
+
require 'thor'
|
2
|
+
|
3
|
+
module NBA
|
4
|
+
class CLI < Thor
|
5
|
+
desc "games DATE", "Retrieve games' scoreboard of date"
|
6
|
+
method_option :date, :aliases => '-d', :desc => "format: YYYYMMDD"
|
7
|
+
def games
|
8
|
+
if options[:date].nil? || options[:date] == 'today'
|
9
|
+
game_date_in_et = (Time.now.utc - 5 * 60 * 60).strftime("%Y%m%d")
|
10
|
+
elsif options[:date] == 'yesterday'
|
11
|
+
game_date_in_et = (Time.now.utc - (5 + 24) * 60 * 60).strftime("%Y%m%d")
|
12
|
+
else
|
13
|
+
game_date_in_et = options[:date]
|
14
|
+
end
|
15
|
+
|
16
|
+
Game.all(game_date_in_et)
|
17
|
+
end
|
18
|
+
|
19
|
+
desc "teams", "Retrieve teams' info, with players' info if `-p` arg is passed"
|
20
|
+
method_option :name, :type => :string, :aliases => "-n", :required => true
|
21
|
+
method_option :players, :type => :boolean, :aliases => "-p", :default => false
|
22
|
+
def teams
|
23
|
+
team_results = Team.all.select { |team| team.name =~ %r|#{options[:name]}|i }
|
24
|
+
|
25
|
+
if team_results.count == 0
|
26
|
+
puts "No team founded with name #{options[:name]}"
|
27
|
+
else
|
28
|
+
team_results.each do |team|
|
29
|
+
team.pretty_print
|
30
|
+
puts "-" * 42
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
data/lib/nba/game.rb
CHANGED
@@ -16,19 +16,33 @@ module NBA
|
|
16
16
|
# >> Final - Trail Blazers 134 : 104 Bobcats
|
17
17
|
# >> Final - Kings 104 : 113 76ers
|
18
18
|
def self.all(date = (Time.now.utc - 5 * 60 * 60).strftime("%Y%m%d"))
|
19
|
-
|
20
|
-
|
19
|
+
results = scoreboard(date)
|
20
|
+
|
21
|
+
if results == 'fail'
|
22
|
+
puts "Fail to fetch game scoreboard/schedule!"
|
23
|
+
else
|
24
|
+
puts scoreboard(date).join("\n")
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
def self.scoreboard(date = (Time.now.utc - 5 * 60 * 60).strftime("%Y%m%d"))
|
29
|
+
begin
|
30
|
+
format_games(results_to_game(results_from_espn(date)))
|
31
|
+
rescue Faraday::Error::ConnectionFailed, Faraday::Error::TimeoutError, Errno::EHOSTUNREACH
|
32
|
+
"fail"
|
33
|
+
end
|
21
34
|
end
|
22
35
|
|
23
36
|
def pretty_format(options = {})
|
24
37
|
self.status.center(options[:status_length].to_i + 1) + " - " + \
|
25
38
|
self.home_team.center(options[:home_length].to_i + 1) + " " + \
|
26
|
-
|
27
|
-
|
39
|
+
self.home_score.center(options[:home_score].to_i + 1) + " : " + \
|
40
|
+
self.away_score.center(options[:away_score].to_i + 1) + " " + \
|
28
41
|
self.away_team.center(options[:away_length].to_i + 1)
|
29
42
|
end
|
30
43
|
|
31
44
|
private
|
45
|
+
|
32
46
|
def initialize(attributes = {})
|
33
47
|
attributes.each do |key, value|
|
34
48
|
instance_variable_set("@#{key}", value) if self.respond_to?(key)
|
@@ -39,13 +53,15 @@ module NBA
|
|
39
53
|
{
|
40
54
|
:status_length => games.map(&:status).map(&:length).max,
|
41
55
|
:home_length => games.map(&:home_team).map(&:length).max,
|
56
|
+
:home_score => games.map(&:home_score).map(&:length).max,
|
42
57
|
:away_length => games.map(&:away_team).map(&:length).max,
|
58
|
+
:away_score => games.map(&:away_score).map(&:length).max
|
43
59
|
}
|
44
60
|
end
|
45
61
|
|
46
|
-
def self.
|
62
|
+
def self.format_games(games)
|
47
63
|
length_options = length_options_of(games)
|
48
|
-
|
64
|
+
games.map { |game| game.pretty_format(length_options) }
|
49
65
|
end
|
50
66
|
|
51
67
|
def self.results_to_game(results)
|
data/lib/nba/player.rb
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
module NBA
|
2
2
|
class Player
|
3
|
-
attr_reader :name, :number, :
|
3
|
+
attr_reader :name, :number, :positions, :from, :to
|
4
4
|
|
5
5
|
def initialize(attributes = {})
|
6
6
|
attributes.each do |key, value|
|
@@ -8,15 +8,19 @@ module NBA
|
|
8
8
|
end
|
9
9
|
end
|
10
10
|
|
11
|
+
def pretty_print
|
12
|
+
"#{self.name}, number #{self.number}, position: #{self.positions.join(', ')}"
|
13
|
+
end
|
14
|
+
|
11
15
|
# Returns an array of Player objects given a team roster
|
12
16
|
def self.all_from_roster(players)
|
13
17
|
players.select{ |player| player['to'].nil? }.map do |player|
|
14
18
|
new(
|
15
|
-
:name
|
16
|
-
:number
|
17
|
-
:
|
18
|
-
:from
|
19
|
-
:to
|
19
|
+
:name => player['player'],
|
20
|
+
:number => player['number'].to_i,
|
21
|
+
:positions => player['position'],
|
22
|
+
:from => player['from'].to_i,
|
23
|
+
:to => "Present"
|
20
24
|
)
|
21
25
|
end
|
22
26
|
end
|
data/lib/nba/team.rb
CHANGED
@@ -1,3 +1,6 @@
|
|
1
|
+
require 'faraday'
|
2
|
+
require 'json'
|
3
|
+
|
1
4
|
module NBA
|
2
5
|
class Team
|
3
6
|
attr_reader :name, :founded, :conference, :division, :championships, :players, :head_coach, :team_stats
|
@@ -27,77 +30,106 @@ module NBA
|
|
27
30
|
@all = nil
|
28
31
|
end
|
29
32
|
|
30
|
-
|
33
|
+
ADJUST_WIDTH = 16
|
34
|
+
def pretty_print
|
35
|
+
puts "%#{ADJUST_WIDTH}s: #{self.name}" % "Name"
|
36
|
+
puts "%#{ADJUST_WIDTH}s: #{self.founded}" % "Founded"
|
37
|
+
puts "%#{ADJUST_WIDTH}s: #{self.conference}" % "Conference"
|
38
|
+
puts "%#{ADJUST_WIDTH}s: #{self.division}" % "Division"
|
39
|
+
puts "%#{ADJUST_WIDTH}s: #{self.coach}" % "Coach"
|
40
|
+
puts "%#{ADJUST_WIDTH}s: #{pretty_print_championships}" % "Championships"
|
41
|
+
puts "%#{ADJUST_WIDTH}s: #{pretty_print_players}" % "Players"
|
42
|
+
end
|
43
|
+
|
44
|
+
private
|
31
45
|
|
32
|
-
|
33
|
-
|
34
|
-
|
46
|
+
def initialize(attributes = {})
|
47
|
+
attributes.each do |key, value|
|
48
|
+
instance_variable_set("@#{key}", value) if self.respond_to?(key)
|
49
|
+
end
|
35
50
|
end
|
36
|
-
end
|
37
51
|
|
38
|
-
|
39
|
-
|
40
|
-
Request.get_teams('/freebase/v1/mqlread', options)
|
41
|
-
end
|
52
|
+
def pretty_print_championships
|
53
|
+
idx = 0
|
42
54
|
|
43
|
-
|
44
|
-
|
45
|
-
|
55
|
+
self.championships.sort.reverse.each_slice(2).inject("") do |string, chams|
|
56
|
+
string << "\n" + (" " * (ADJUST_WIDTH + 2)) if (idx += 1) != 1
|
57
|
+
string << chams.join(", ")
|
58
|
+
end
|
59
|
+
end
|
46
60
|
|
47
|
-
|
48
|
-
|
49
|
-
end
|
61
|
+
def pretty_print_players
|
62
|
+
idx = 0
|
50
63
|
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
64
|
+
self.players.sort_by{|p| -p.number}.reverse.inject("") do |string, player|
|
65
|
+
string << "\n" + (" " * (ADJUST_WIDTH + 2)) if (idx += 1) != 1
|
66
|
+
string << player.pretty_print
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
def self.results_from_freebase
|
71
|
+
options = {:query => mql_query}
|
72
|
+
Request.get_teams('/freebase/v1/mqlread', options)
|
73
|
+
end
|
74
|
+
|
75
|
+
def self.results_from_cache
|
76
|
+
JSON.load(file_from_cache('teams.json').read)
|
77
|
+
end
|
78
|
+
|
79
|
+
def self.file_from_cache(file_name)
|
80
|
+
File.new(File.expand_path('../../../cache', __FILE__) + '/' + file_name)
|
65
81
|
end
|
66
|
-
end
|
67
82
|
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
"
|
90
|
-
"
|
91
|
-
"
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
"
|
83
|
+
def self.results_to_team(results)
|
84
|
+
results['result'].map do |result|
|
85
|
+
players = result['/sports/sports_team/roster']
|
86
|
+
|
87
|
+
new(
|
88
|
+
:name => result['name'],
|
89
|
+
:conference => result['/basketball/basketball_team/conference'],
|
90
|
+
:division => result['/basketball/basketball_team/division'],
|
91
|
+
:head_coach => result['/basketball/basketball_team/head_coach'],
|
92
|
+
:team_stats => result['/basketball/basketball_team/team_stats'],
|
93
|
+
:founded => result['/sports/sports_team/founded'].to_i,
|
94
|
+
:championships => result['/sports/sports_team/championships'],
|
95
|
+
:players => (players ? Player.all_from_roster(players) : [])
|
96
|
+
)
|
97
|
+
end
|
98
|
+
end
|
99
|
+
|
100
|
+
# Returns the MQL query for teams, as a Ruby hash
|
101
|
+
def self.mql_query
|
102
|
+
query = <<-eos
|
103
|
+
[{
|
104
|
+
"name": null,
|
105
|
+
"mid": null,
|
106
|
+
"/basketball/basketball_team/head_coach": null,
|
107
|
+
"/basketball/basketball_team/conference": null,
|
108
|
+
"/basketball/basketball_team/division": null,
|
109
|
+
"/sports/sports_team/founded": null,
|
110
|
+
"/sports/sports_team/championships": [],
|
111
|
+
"/sports/sports_team/roster": [{
|
112
|
+
"number": null,
|
113
|
+
"player": null,
|
114
|
+
"from": null,
|
115
|
+
"to": null,
|
116
|
+
"position": [],
|
117
|
+
"sort": "player"
|
118
|
+
}],
|
119
|
+
"/basketball/basketball_team/team_stats": [{
|
120
|
+
"optional": true,
|
121
|
+
"season": null,
|
122
|
+
"wins": null,
|
123
|
+
"losses": null
|
124
|
+
}],
|
125
|
+
"sort": "name",
|
126
|
+
"type": "/basketball/basketball_team",
|
127
|
+
"/sports/sports_team/league": [{
|
128
|
+
"league": "National Basketball Association"
|
129
|
+
}]
|
97
130
|
}]
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
end
|
131
|
+
eos
|
132
|
+
query.gsub!("\n", '')
|
133
|
+
end
|
102
134
|
end
|
103
135
|
end
|