mlb_terminal 0.0.3 → 0.0.4

Sign up to get free protection for your applications and to get access to all the features.
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- mlb_terminal (0.0.2)
4
+ mlb_terminal (0.0.4)
5
5
  activesupport (~> 3.2.8)
6
6
  commander (~> 4.1.2)
7
7
  nokogiri (~> 1.5.5)
data/README.md CHANGED
@@ -1,18 +1,20 @@
1
- # MLB Terminal
1
+ nal
2
2
 
3
3
  Access to MLB baseball scores in the terminal.
4
4
 
5
5
  ## Overview
6
6
 
7
- Don't you just wish you could have a little terminal app to stream out real-time stats for a MLB baseball game? Look no further!
7
+ Don't you just wish you could have a little terminal app to stream out real-time stats for a MLB baseball game? Look no further! _Please note, the use of this data is subjected to the terms put forth by the MLB. More information can be found here: [http://gdx.mlb.com/components/copyright.txt](http://gdx.mlb.com/components/copyright.txt). You're okay if you're using this data for individual use!_
8
8
 
9
9
  ### Syntax
10
10
 
11
11
  #### Commands
12
12
 
13
- * help: Display global or [command] help documentation.
14
- * games: Print out a list of scheduled games for the specified date
15
- * game: Print out play-by-play events for a specific game. Use `--pitches` to output realtime pitch trajectory data.
13
+ To find out more about a specific command, use `mlb [command] --help` to view the appropriate documentation.
14
+
15
+ * `help`: Display global or [command] help documentation.
16
+ * `games [options]`: Print out a list of scheduled games for the specified date
17
+ * `game [options] [game_number]`: Print out play-by-play events for a specific game. Use `--pitches` to output realtime pitch trajectory data.
16
18
 
17
19
  #### Global options
18
20
 
@@ -22,6 +24,75 @@ Don't you just wish you could have a little terminal app to stream out real-time
22
24
 
23
25
  * -t, --trace: Display backtrace when an error occurs
24
26
 
27
+ ### Data Output Format
28
+
29
+ Each command outputs data in tab-separated format. When outputting data for a game in progress, the application will continue to pipe in data as it is made available.
30
+
31
+ #### `games` (Game listings)
32
+
33
+ 1. Game index. A numbered value unique to the specified date that is referenced in the `game` command.
34
+ 2. Opposing teams. A string containing: `<Away Team> (Wins - Losses) @ <Home Team> (Wins - Losses).
35
+ 3. Starting time and status.
36
+ 4. Current score.
37
+
38
+ #### `game` (Game events)
39
+
40
+ 1. Event time.
41
+ 2. Inning.
42
+ 3. Event number.
43
+ 4. Event description.
44
+
45
+ #### `game --pitches` (Pitch events)
46
+
47
+ 1. Pitch time.
48
+ 2. Inning.
49
+ 3. Top/Bottom of inning.
50
+ 4. Pitcher name.
51
+ 5. Batter name.
52
+ 6. Pitch type. (S-Strike, B-Ball, X-hit)
53
+ 7. X (x). The horizontal location of the pitch as it crosses the home plate. Units: Old Gameday coordinate system
54
+ 8. Y (y). The vertical location of the pitch as it crosses the home plate. Units: Old Gameday coordinate system
55
+ 9. Start speed (start_speed). The initial speed of the pitch. Units: miles per hour
56
+ 10. End speed (end_speed). The speed measured as it crosses the home plate. Units: miles per hour
57
+ 11. Top of Strike Zone (sz_top). The distance from the ground to the top of the strike zone. Units: feet
58
+ 12. Bottom of Strike Zone (sz_bot). The distance from the ground to the bottom of the strike zone. Units: feet
59
+ 13. Horizontal movement (pfx_x). The horizontal movement of a pitch relative to a theoretical pitch thrown at the same speed with no spin-induced movement. Measured at 40 feet from the home plate. Units: inches
60
+ 14. Vertical movement (pfx_z). The vertical movement of a pitch relative to a theoretical pitch thrown at the same speed with no spin-induced movement. Measured at 40 feet from the home plate. Units: inches
61
+ 15. Horizontal pitch location at home plate (px). The horizontal location of the pitch as it crosses home plate from the perspective of the umpire. Units: feet
62
+ 16. Vertical pitch location at home plate (pz). The height of the pitch as it crosses the front of home plate. Units: feet
63
+ 17. Initial horizontal measurement for pitch (x0). Initial horizontal measurement of pitch as measured by PITCHf/x. Units: feet
64
+ 18. Initial depth measurement for pitch (y0). Initial deptch measurement of pitch as measured by PITCHf/x. Note that this is fixed per stadium and typically located around 40-50 feet from home plate. Units: feet
65
+ 19. Initial height measurement for pitch (z0). Initial height measurement of pitch as measured by PITCHf/x. Units: feet
66
+ 20. Initial x velocity (vxo). Initial velocity in the horizontal direction at the initial point. Units: feet per second
67
+ 21. Initial y velocity (vxo). Initial velocity in the depth-wise direction at the initial point. Units: feet per second
68
+ 22. Initial z velocity (vxo). Initial velocity in the vertical direction at the initial point. Units: feet per second
69
+ 23. Breaking point (break_y). The distance from the home plate in which the pitch achieved its greatest deviation from the straight line path between the release point and the front of home plate. Units: feet
70
+ 24. Breaking angle (break_angle). The angle at which the pitch crossed the front of home plate as seen by the umpire. Units: degrees
71
+ 25. Breaking length (break_length). The greatest distance between the pitch's trajectory and the straight path between release and home plate. Units: inches
72
+ 26. Pitch type (pitch_type). Pitch type as classified by the PITCHf/x system.
73
+ * FA = Fastball
74
+ * FF = Four-seam fastball
75
+ * FT = Two-seam fastball
76
+ * FC = Fastball (cutter)
77
+ * FS / SI / SF = Fastball (sinker, split-fingered)
78
+ * SL = Slider
79
+ * CH = Changeup
80
+ * CB / CU = Curveball
81
+ * KC = Knuckle-curve
82
+ * KN = Knuckleball
83
+ * EP = Eephus
84
+ * UN / XX = Unidentified
85
+ * PO / FO = Pitch out
86
+ 27. Pitch type confidence (type_confidence). A rating corresponding to the liklihood of the pitch type classification.
87
+ 28. Pitch zone (zone).
88
+ 29. Nasty factor (nasty). A auto-generated factor that describes the difficulty in hitting the pitch.
89
+ 30. Spin direction (spin_dir).
90
+ 31. Spin rate (spin_rate).
91
+ 32. Comments (cc).
92
+ 33. Unknown (mt).
93
+
94
+ For more information regarding PITCHf/x tracjectory data, please visit [http://fastballs.wordpress.com/category/pitchfx-glossary/](http://fastballs.wordpress.com/category/pitchfx-glossary/).
95
+
25
96
  ### Examples
26
97
 
27
98
  > # List todays games
data/bin/mlb CHANGED
@@ -10,7 +10,7 @@ program :description, 'Stream MLB games into the terminal'
10
10
 
11
11
  command :games do |c|
12
12
  c.syntax = 'mlb games [options] [date]'
13
- c.summary = 'Print out a list of scheduled games for the specified date'
13
+ c.summary = 'Print out a list of scheduled games for the specified date.'
14
14
  c.description = 'Print out a tab-seperated value list to STDOUT wih columns ' \
15
15
  'for index, team names, game status, and current score.'
16
16
  c.example 'description', 'mlb --date "2012-09-28" | grep Nationals'
@@ -30,6 +30,97 @@ command :games do |c|
30
30
  end
31
31
  end
32
32
 
33
+ command :pitchers do |c|
34
+ c.syntax = 'mlb pitchers [options] [game-number]'
35
+ c.summary = 'Print out a list of pitchers for the specified date and game index.'
36
+ c.description = 'Print out a tab-seperated value list to STDOUT wih columns ' \
37
+ 'for team, pitcher id, and pitcher name. Note, this prints out ' \
38
+ 'the full line-up on the team.'
39
+ c.example 'description', 'mlb pitchers 11 | grep "Edwin Jackson"'
40
+ c.option '--date STRING', String, 'List pitchers for specified date (Default: today)'
41
+ c.action do |args, options|
42
+ options.default :date => Time.now.to_date.to_s
43
+
44
+ # Validate input
45
+ if (Float(args.first) rescue nil).nil?
46
+ puts "Error: Game number must be a valid integer"
47
+ break
48
+ elsif (args.first.to_i < 0)
49
+ puts "Error: Game number must be greater than or equal to 0"
50
+ break
51
+ end
52
+
53
+ game_number = args.first.to_i
54
+
55
+ gameday_id = MLBTerminal::Game.list(Date.parse options.date)[game_number][:game_id]
56
+
57
+ MLBTerminal::Pitcher.list(gameday_id).each_pair do |pitcher_id, pitcher_info|
58
+ puts [
59
+ pitcher_info[:team],
60
+ pitcher_id,
61
+ pitcher_info[:name]].join("\t")
62
+ end
63
+ end
64
+ end
65
+
66
+ command :pitcher do |c|
67
+ c.syntax = 'mlb pitcher [options] [game-number] [pitcher-id]'
68
+ c.summary = 'Print out a list of summary statistics for pitcher tendencies.'
69
+ c.description = 'Print out a tab-seperated value list to STDOUT wih columns ' \
70
+ 'for pitcher name, pitcher team, date, away team, home team, ' \
71
+ 'pitch count, average speed, pitch type, pitch count, average ' \
72
+ 'movement, pfx, velocity, average initial x-position, and ' \
73
+ 'average initial z-position.'
74
+ c.example 'description', 'mlb pitchers --date 2012-09-30 11 | grep "Ross Detwiler" ' \
75
+ '| cut -f 2 | xargs mlb pitcher --date 2012-09-30 11'
76
+ c.option '--date STRING', String, 'List pitchers for specified date (Default: today)'
77
+ c.action do |args, options|
78
+ game_number, pitcher_id = args
79
+ options.default :date => Time.now.to_date.to_s
80
+
81
+ # Validate input
82
+ if (Float(game_number) rescue nil).nil?
83
+ puts "Error: Game number must be a valid integer"
84
+ break
85
+ elsif (game_number.to_i < 0)
86
+ puts "Error: Game number must be greater than or equal to 0"
87
+ break
88
+ end
89
+
90
+ if (Float(pitcher_id) rescue nil).nil?
91
+ puts "Error: Pitcher ID must be a valid integer"
92
+ break
93
+ elsif (pitcher_id.to_i < 0)
94
+ puts "Error: Pitcher ID must be greater than or equal to 0"
95
+ break
96
+ end
97
+
98
+ game_number = game_number.to_i
99
+ games = MLBTerminal::Game.list(Date.parse options.date)
100
+ gameday_id = games[game_number][:game_id]
101
+ pitcher = MLBTerminal::Pitcher.new(gameday_id, pitcher_id)
102
+
103
+ pitcher.pitch_tendency_history.each do |game|
104
+ game_info = MLBTerminal::Game.parse_gameday_id(game[:gameday_id])
105
+ puts [
106
+ game[:pitcher_name],
107
+ game[:pitcher_team],
108
+ Date.new(game_info[:year].to_i, game_info[:month].to_i, game_info[:day].to_i),
109
+ MLBTerminal::TEAMS[game_info[:away_team].to_sym],
110
+ MLBTerminal::TEAMS[game_info[:home_team].to_sym],
111
+ game[:pitch_count],
112
+ game[:avg_speed],
113
+ game[:pitch_type],
114
+ game[:pitch_number],
115
+ game[:movement],
116
+ game[:pfx],
117
+ game[:vel],
118
+ game[:avg_x0],
119
+ game[:avg_z0]].join("\t")
120
+ end
121
+ end
122
+ end
123
+
33
124
  command :game do |c|
34
125
  c.syntax = 'mlb game [options] [game-number]'
35
126
  c.summary = 'Print game events'
data/lib/mlb_terminal.rb CHANGED
@@ -1,2 +1,4 @@
1
+ require 'mlb_terminal/globals'
1
2
  require 'mlb_terminal/version'
2
3
  require 'mlb_terminal/game'
4
+ require 'mlb_terminal/pitcher'
@@ -4,7 +4,6 @@ require 'open-uri'
4
4
  require 'active_support/core_ext/integer/inflections'
5
5
 
6
6
  module MLBTerminal
7
- MLB_BASE_URL = 'http://gd2.mlb.com/components/game/mlb'
8
7
 
9
8
  class Game
10
9
  def self.list(date = Time.now.to_date)
@@ -31,9 +30,7 @@ module MLBTerminal
31
30
  end
32
31
 
33
32
  def initialize(gameday)
34
- @gameday = gameday
35
- year, month, day, game_name = /([0-9]{4})_([0-9]{2})_([0-9]{2})_(.*)/.match(@gameday).to_a.slice(1,4)
36
- @base_url = "#{Game.base_url_for_date(Date.new(year.to_i, month.to_i, day.to_i))}/gid_#{@gameday}"
33
+ @base_url = Game.parse_gameday_id_to_url gameday
37
34
  end
38
35
 
39
36
  def events(delay = 5, &block)
@@ -59,9 +56,8 @@ module MLBTerminal
59
56
 
60
57
  last_atbat = doc.xpath("//game/inning/*/atbat/@num").map(&:value).map(&:to_i).max
61
58
 
62
- sleep delay
63
-
64
59
  if doc.xpath("//game").first["ind"] != "F"
60
+ sleep delay
65
61
  doc = Nokogiri::HTML(open "#{@base_url}/inning/inning_all.xml")
66
62
  end
67
63
  end while game_status != "F"
@@ -125,9 +121,8 @@ module MLBTerminal
125
121
 
126
122
  last_pitch = doc.xpath("//game/inning/*/*/pitch/@id").map(&:value).map(&:to_i).max
127
123
 
128
- sleep delay
129
-
130
124
  if doc.xpath("//game").first["ind"] != "F"
125
+ sleep delay
131
126
  doc = Nokogiri::HTML(open "#{@base_url}/inning/inning_all.xml")
132
127
  end
133
128
  end while game_status != "F"
@@ -138,6 +133,21 @@ module MLBTerminal
138
133
  "#{MLB_BASE_URL}/year_#{date.year}/month_#{"%02d" % date.month}/day_#{"%02d" % date.day}"
139
134
  end
140
135
 
136
+ def self.parse_gameday_id_to_url(gameday)
137
+ game_info = Game.parse_gameday_id gameday
138
+ "#{Game.base_url_for_date(Date.new(game_info[:year].to_i, game_info[:month].to_i, game_info[:day].to_i))}/gid_" \
139
+ "#{game_info[:year]}_" \
140
+ "#{game_info[:month]}_" \
141
+ "#{game_info[:day]}_" \
142
+ "#{game_info[:away_team]}mlb_" \
143
+ "#{game_info[:home_team]}mlb_" \
144
+ "#{game_info[:game_number]}"
145
+ end
146
+
147
+ def self.parse_gameday_id(gameday)
148
+ Hash[[:year, :month, :day, :away_team, :home_team, :game_number].zip(/[gid_]*([0-9]{4})_([0-9]{2})_([0-9]{2})_([a-z]{3})mlb_([a-z]{3})mlb_([0-9])/.match(gameday).to_a.slice(1,6))]
149
+ end
150
+
141
151
  private
142
152
 
143
153
  def player_lookup
@@ -0,0 +1,57 @@
1
+ module MLBTerminal
2
+
3
+ MLB_BASE_URL = 'http://gd2.mlb.com/components/game/mlb'
4
+
5
+ TEAMS = {
6
+ :ana => "Los Angeles Angels",
7
+ :ari => "Arizona Diamondbacks",
8
+ :atl => "Atlanta Braves",
9
+ :bal => "Baltimore Orioles",
10
+ :bos => "Boston Red Sox",
11
+ :cha => "Chicago White Sox",
12
+ :chn => "Chicago Cubs",
13
+ :cin => "Cincinnati Reds",
14
+ :cle => "Cleveland Indians",
15
+ :col => "Colorado Rockies",
16
+ :det => "Detroit Tigers",
17
+ :hou => "Houston Astros",
18
+ :kca => "Kansas City Royals",
19
+ :lan => "Los Angeles Dodgers",
20
+ :mia => "Miami Marlins",
21
+ :mil => "Milwaukee Brewers",
22
+ :min => "Minnesota Twins",
23
+ :nya => "New York Yankees",
24
+ :nyn => "New York Mets",
25
+ :oak => "Oakland Athletics",
26
+ :phi => "Philadelphia Phillies",
27
+ :pit => "Pittsburgh Pirates",
28
+ :sdn => "San Diego Padres",
29
+ :sea => "Seattle Mariners",
30
+ :sfn => "San Francisco Giants",
31
+ :sln => "Saint Louis Cardinals",
32
+ :tba => "Tampa Bay Rays",
33
+ :tex => "Texas Rangers",
34
+ :tor => "Toronto Blue Jays",
35
+ :was => "Washington Nationals"}
36
+
37
+ PITCH_TYPES = {
38
+ "FA" => "Fastball",
39
+ "FF" => "Four-seam Fastball",
40
+ "FT" => "Two-seam Fastball",
41
+ "FC" => "Fastball / Cutter",
42
+ "FS" => "Fastball / Sinker",
43
+ "SI" => "Sinker",
44
+ "SF" => "Split-Fingered Fastball",
45
+ "SL" => "Slider",
46
+ "CH" => "Changeup",
47
+ "CB" => "Curveball",
48
+ "CU" => "Curveball",
49
+ "KC" => "Kunckle-curve",
50
+ "KN" => "Kunckleball",
51
+ "EP" => "Eephus",
52
+ "UN" => "Unidentified",
53
+ "XX" => "Unidentified",
54
+ "PO" => "Pitch out",
55
+ "FO" => "Pitch out"}
56
+
57
+ end
@@ -0,0 +1,44 @@
1
+ require 'nokogiri'
2
+ require 'open-uri'
3
+
4
+ module MLBTerminal
5
+ class Pitcher
6
+
7
+ def self.list(gameday)
8
+ base_url = MLBTerminal::Game.parse_gameday_id_to_url gameday
9
+ doc = Nokogiri::HTML(open( "#{base_url}/players.xml"))
10
+ Hash[doc.xpath("//game/team/player[@position='P']").map{|x| [x["id"], {:team => x.xpath("..").first["name"], :name => "#{x["first"]} #{x["last"]}"}]}]
11
+ end
12
+
13
+ def initialize(gameday, pitcher_id)
14
+ @base_url = "#{MLBTerminal::Game.parse_gameday_id_to_url gameday}/premium/pitchers/#{pitcher_id}"
15
+ pitcher = Pitcher.list(gameday)[pitcher_id]
16
+ @team = pitcher[:team]
17
+ @name = pitcher[:name]
18
+ end
19
+
20
+ def pitch_tendency_history(&block)
21
+ doc = Nokogiri::HTML(open( "#{@base_url}/pitchtendencies_history.xml"))
22
+
23
+ Enumerator.new do |y|
24
+ doc.xpath("//pitchtendencies/games/game").each do |game|
25
+ game.xpath("types/type").each do |type|
26
+ y.yield({
27
+ :pitcher_name => @name,
28
+ :pitcher_team => @team,
29
+ :gameday_id => game["id"],
30
+ :pitch_count => game["num"],
31
+ :avg_speed => game["vel"],
32
+ :pitch_type => PITCH_TYPES[type["id"]],
33
+ :pitch_number => type["num"],
34
+ :movement => type["movement"],
35
+ :pfx => type["pfx"],
36
+ :vel => type["vel"],
37
+ :avg_x0 => type["avg_x0"],
38
+ :avg_z0 => type["avg_z0"] })
39
+ end
40
+ end
41
+ end.each(&block)
42
+ end
43
+ end
44
+ end
@@ -1,3 +1,3 @@
1
1
  module MLBTerminal
2
- VERSION = "0.0.3"
2
+ VERSION = "0.0.4"
3
3
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: mlb_terminal
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.3
4
+ version: 0.0.4
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2012-09-30 00:00:00.000000000 Z
12
+ date: 2012-10-01 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: commander
@@ -77,6 +77,8 @@ files:
77
77
  - bin/mlb
78
78
  - lib/mlb_terminal.rb
79
79
  - lib/mlb_terminal/game.rb
80
+ - lib/mlb_terminal/globals.rb
81
+ - lib/mlb_terminal/pitcher.rb
80
82
  - lib/mlb_terminal/version.rb
81
83
  - mlb_terminal.gemspec
82
84
  homepage: https://github.com/slnovak/mlb_terminal