sports_data_api 0.0.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.
data/.gitignore ADDED
@@ -0,0 +1,25 @@
1
+ *.gem
2
+ *.rbc
3
+ .bundle
4
+ .config
5
+ .yardoc
6
+ Gemfile.lock
7
+ InstalledFiles
8
+ _yardoc
9
+ coverage
10
+ doc/
11
+ lib/bundler/man
12
+ pkg
13
+ rdoc
14
+ spec/reports
15
+ test/tmp
16
+ test/version_tmp
17
+ tmp
18
+
19
+ # YARD artifacts
20
+ .yardoc
21
+ _yardoc
22
+ doc/
23
+
24
+ # OSX artifacts
25
+ .DS_Store
data/.rspec ADDED
@@ -0,0 +1,2 @@
1
+ --color
2
+ --format documentation
data/.rvmrc ADDED
@@ -0,0 +1,38 @@
1
+ #!/usr/bin/env bash
2
+
3
+ # This is an RVM Project .rvmrc file, used to automatically load the ruby
4
+ # development environment upon cd'ing into the directory
5
+
6
+ # First we specify our desired <ruby>[@<gemset>], the @gemset name is optional,
7
+ # Only full ruby name is supported here, for short names use:
8
+ # echo "rvm use 1.9.3" > .rvmrc
9
+ environment_id="ruby-1.9.3-p194@sports-data"
10
+
11
+ # Uncomment the following lines if you want to verify rvm version per project
12
+ # rvmrc_rvm_version="1.14.11 (stable)" # 1.10.1 seams as a safe start
13
+ # eval "$(echo ${rvm_version}.${rvmrc_rvm_version} | awk -F. '{print "[[ "$1*65536+$2*256+$3" -ge "$4*65536+$5*256+$6" ]]"}' )" || {
14
+ # echo "This .rvmrc file requires at least RVM ${rvmrc_rvm_version}, aborting loading."
15
+ # return 1
16
+ # }
17
+
18
+ # First we attempt to load the desired environment directly from the environment
19
+ # file. This is very fast and efficient compared to running through the entire
20
+ # CLI and selector. If you want feedback on which environment was used then
21
+ # insert the word 'use' after --create as this triggers verbose mode.
22
+ if [[ -d "${rvm_path:-$HOME/.rvm}/environments"
23
+ && -s "${rvm_path:-$HOME/.rvm}/environments/$environment_id" ]]
24
+ then
25
+ \. "${rvm_path:-$HOME/.rvm}/environments/$environment_id"
26
+ [[ -s "${rvm_path:-$HOME/.rvm}/hooks/after_use" ]] &&
27
+ \. "${rvm_path:-$HOME/.rvm}/hooks/after_use" || true
28
+ if [[ $- == *i* ]] # check for interactive shells
29
+ then echo "Using: $(tput setaf 2)$GEM_HOME$(tput sgr0)" # show the user the ruby and gemset they are using in green
30
+ else echo "Using: $GEM_HOME" # don't use colors in non-interactive shells
31
+ fi
32
+ else
33
+ # If the environment file has not yet been created, use the RVM CLI to select.
34
+ rvm --create use "$environment_id" || {
35
+ echo "Failed to create RVM environment '${environment_id}'."
36
+ return 1
37
+ }
38
+ fi
data/.travis.yml ADDED
@@ -0,0 +1,4 @@
1
+ language: ruby
2
+ rvm:
3
+ - 1.9.2
4
+ - 1.9.3
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in sports_data_api.gemspec
4
+ gemspec
data/Guardfile ADDED
@@ -0,0 +1,9 @@
1
+ # A sample Guardfile
2
+ # More info at https://github.com/guard/guard#readme
3
+
4
+ guard 'rspec' do
5
+ watch(%r{^spec/.+_spec\.rb$})
6
+ watch(%r{^lib/(.+)\.rb$}) { |m| "spec/lib/#{m[1]}_spec.rb" }
7
+ watch('spec/spec_helper.rb') { "spec" }
8
+ end
9
+
data/LICENSE.md ADDED
@@ -0,0 +1,24 @@
1
+
2
+ Copyright (c) 2012 Ryan Lovelett ( [@rlovelett](http://twitter.com/#!/rlovelett) )
3
+ =================================================================================================
4
+
5
+ The "SportsDataApi" RubyGem is released under the **MIT LICENSE**
6
+ ----------------------------------------------------------
7
+
8
+ Permission is hereby granted, free of charge, to any person obtaining a copy
9
+ of this software and associated documentation files (the "Software"), to deal
10
+ in the Software without restriction, including without limitation the rights
11
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
12
+ copies of the Software, and to permit persons to whom the Software is
13
+ furnished to do so, subject to the following conditions:
14
+
15
+ The above copyright notice and this permission notice shall be included in
16
+ all copies or substantial portions of the Software.
17
+
18
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
21
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
22
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
23
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
24
+ THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,57 @@
1
+ # SportsDataApi [![Build Status](https://travis-ci.org/RLovelett/sports_data_api.png?branch=master)](https://travis-ci.org/RLovelett/sports_data_api)
2
+
3
+ SportsDataApi is an attempt to make a Ruby interface to the
4
+ [SportsData](http://www.sportsdatallc.com/) API. The goal is to
5
+ eventaully support the full API. Pull requests that extend the API
6
+ support are always welcome.
7
+
8
+ [SportsData](http://www.sportsdatallc.com/)’s comprehensive data coverage includes all major U.S. sports,
9
+ plus hundreds of leagues throughout the world. Their live game analysts
10
+ capture every possible event of every game, in real time and with
11
+ accuracy standards developed from years of experience.
12
+
13
+ ## Author
14
+
15
+ [Ryan Lovelett](http://ryan.lovelett.me/) ( [@rlovelett](http://twitter.com/#!/rlovelett) )
16
+
17
+ Drop me a message for any questions, suggestions, requests, bugs or
18
+ submit them to the [issue
19
+ log](https://github.com/rlovelett/sports_data_api/issues).
20
+
21
+ ## API Support
22
+
23
+ * [NFL](http://developer.sportsdatallc.com/docs/NFL_API)
24
+ * TODO
25
+ 1. [MLB](http://developer.sportsdatallc.com/docs/MLB_API)
26
+ 2. [NHL](http://developer.sportsdatallc.com/docs/NHL_API)
27
+ 3. [NBA](http://developer.sportsdatallc.com/docs/NBA_API)
28
+ 4. [NCAA Basketball](http://developer.sportsdatallc.com/docs/NCAA_Mens_Backetball)
29
+ 5. [NCAA Football](http://developer.sportsdatallc.com/docs/NCAA_Football_API)
30
+
31
+ ## Installation
32
+
33
+ Add this line to your application's Gemfile:
34
+
35
+ gem 'sports_data_api'
36
+
37
+ And then execute:
38
+
39
+ $ bundle
40
+
41
+ Or install it yourself as:
42
+
43
+ $ gem install sports_data_api
44
+
45
+ ## Usage
46
+
47
+ The specs for this Gem should give you some idea of how to make use of
48
+ the API. For now they will be the usage information. As always Pull
49
+ Requests for better documentation are always welcome.
50
+
51
+ ## Contributing
52
+
53
+ 1. Fork it
54
+ 2. Create a topic branch (`git checkout -b topic`)
55
+ 3. Make your changes
56
+ 4. Squash your changes into one commit
57
+ 5. Create new Pull Request against this squashed commit
data/Rakefile ADDED
@@ -0,0 +1,7 @@
1
+ #!/usr/bin/env rake
2
+ require "bundler/gem_tasks"
3
+ require "rspec/core/rake_task"
4
+
5
+ RSpec::Core::RakeTask.new(:spec)
6
+
7
+ task default: :spec
data/lib/nfl.rb ADDED
@@ -0,0 +1,90 @@
1
+ module SportsDataApi
2
+ module Nfl
3
+
4
+ class Exception < ::Exception
5
+ end
6
+
7
+ class Season
8
+ attr_reader :year, :type, :weeks
9
+
10
+ def initialize(xml)
11
+ @weeks = []
12
+ if xml.is_a? Nokogiri::XML::NodeSet
13
+ @year = xml.first["season"].to_i
14
+ @type = xml.first["type"].to_sym
15
+ @weeks = xml.first.xpath("week").map do |week_xml|
16
+ Week.new(week_xml)
17
+ end
18
+ end
19
+ end
20
+ end
21
+
22
+ class Week
23
+ attr_reader :number, :games
24
+
25
+ def initialize(xml)
26
+ @games = []
27
+ if xml.is_a? Nokogiri::XML::Element
28
+ @number = xml["week"].to_i
29
+ @games = xml.xpath("game").map do |game_xml|
30
+ Game.new(game_xml)
31
+ end
32
+ end
33
+ end
34
+ end
35
+
36
+ class Game
37
+ attr_reader :id, :scheduled, :home, :away, :status
38
+
39
+ def initialize(xml)
40
+ if xml.is_a? Nokogiri::XML::Element
41
+ @id = xml["id"]
42
+ @scheduled = Time.parse xml["scheduled"]
43
+ @home = xml["home"]
44
+ @away = xml["away"]
45
+ @status = xml["status"]
46
+ end
47
+ end
48
+ end
49
+
50
+ BASE_URL = "http://api.sportsdatallc.org/nfl-%{access_level}%{version}"
51
+ SEASONS = [:PRE, :REG, :PST]
52
+
53
+ def self.schedule(year, season, version = 1)
54
+ base_url = BASE_URL % { access_level: SportsDataApi.access_level, version: version }
55
+ season = season.to_s.upcase.to_sym
56
+ raise SportsDataApi::Nfl::Exception.new("#{season} is not a valid season") unless season?(season)
57
+ url = "#{base_url}/#{year}/#{season}/schedule.xml"
58
+
59
+ begin
60
+ # Perform the request
61
+ response = RestClient.get(url, params: { api_key: SportsDataApi.key })
62
+
63
+ # Load the XML and ignore namespaces in Nokogiri
64
+ schedule = Nokogiri::XML(response.to_s)
65
+ schedule.remove_namespaces!
66
+
67
+ return Season.new(schedule.xpath("/season"))
68
+ rescue RestClient::Exception => e
69
+ message = if e.response.headers.key? :x_server_error
70
+ JSON.parse(error_json, { symbolize_names: true })[:message]
71
+ elsif e.response.headers.key? :x_mashery_error_code
72
+ e.response.headers[:x_mashery_error_code]
73
+ else
74
+ "The server did not specify a message"
75
+ end
76
+ raise SportsDataApi::Exception, message
77
+ end
78
+ end
79
+
80
+ ##
81
+ # Check if the requested season is a valid
82
+ # NFL season type.
83
+ #
84
+ # The only valid types are: :PRE, :REG, :PST
85
+ def self.season?(season)
86
+ SEASONS.include?(season)
87
+ end
88
+
89
+ end
90
+ end
@@ -0,0 +1,3 @@
1
+ module SportsDataApi
2
+ VERSION = "0.0.1"
3
+ end
@@ -0,0 +1,18 @@
1
+ require "sports_data_api/version"
2
+ require "nokogiri"
3
+ require "rest_client"
4
+ require "time"
5
+
6
+ module SportsDataApi
7
+ def self.key
8
+ "garbage"
9
+ end
10
+
11
+ def self.access_level
12
+ "t"
13
+ end
14
+
15
+ autoload :Nfl, File.join(File.dirname(__FILE__), 'nfl')
16
+
17
+ class Exception < ::Exception; end
18
+ end
@@ -0,0 +1,67 @@
1
+ require 'spec_helper'
2
+
3
+ describe SportsDataApi::Nfl do
4
+ let(:key) { "1234567890abcdef" }
5
+ describe ".schedule" do
6
+ it "creates a valid Sports Data LLC url" do
7
+ SportsDataApi.stub(:key).and_return(key)
8
+ RestClient.stub(:get).with("http://api.sportsdatallc.org/nfl-t1/2012/REG/schedule.xml", params: { api_key: key }).and_return(schedule_xml)
9
+ subject.schedule(2012, :REG)
10
+ end
11
+ it "creates a SportsDataApi::Exception when there is no response from the api" do
12
+ error = RestClient::ResourceNotFound.new
13
+ error.stub_chain(:response, :headers).and_return(Hash.new)
14
+ SportsDataApi.stub(:key).and_return(key)
15
+ RestClient.stub(:get).and_raise(error)
16
+ expect { subject.schedule(2999, :REG) }.to raise_error(SportsDataApi::Exception)
17
+ end
18
+
19
+ describe "returned data structures" do
20
+ before(:each) { RestClient.stub(:get).and_return(schedule_xml) }
21
+ let(:season) { SportsDataApi::Nfl.schedule(2012, :REG) }
22
+ describe "SportsDataApi::Nfl::Season" do
23
+ subject { season }
24
+ it { should be_an_instance_of(SportsDataApi::Nfl::Season) }
25
+ its(:year) { should eq 2012 }
26
+ its(:type) { should eq :REG }
27
+ its(:weeks) { should have(17).weeks }
28
+ end
29
+ describe "SportsDataApi::Nfl::Week" do
30
+ subject { season.weeks.first }
31
+ it { should be_an_instance_of(SportsDataApi::Nfl::Week) }
32
+ its(:number) { should eq 1 }
33
+ its(:games) { should have(16).games }
34
+ end
35
+ describe "SportsDataApi::Nfl::Game" do
36
+ subject { season.weeks.first.games.first }
37
+ it { should be_an_instance_of(SportsDataApi::Nfl::Game) }
38
+ its(:id) { should eq "8c0bce5a-7ca2-41e5-9838-d1b8c356ddc3" }
39
+ its(:scheduled) { should eq Time.new(2012, 9, 5, 19, 30, 00, "-05:00") }
40
+ its(:home) { should eq "NYG" }
41
+ its(:away) { should eq "DAL" }
42
+ its(:status) { should eq "closed" }
43
+ end
44
+ end
45
+ end
46
+
47
+ describe ".season?" do
48
+ context :PRE do
49
+ it { subject.season?(:PRE).should be_true }
50
+ end
51
+ context :REG do
52
+ it { subject.season?(:REG).should be_true }
53
+ end
54
+ context :PST do
55
+ it { subject.season?(:PST).should be_true }
56
+ end
57
+ context :pre do
58
+ it { subject.season?(:pre).should be_false }
59
+ end
60
+ context :reg do
61
+ it { subject.season?(:reg).should be_false }
62
+ end
63
+ context :pst do
64
+ it { subject.season?(:pst).should be_false }
65
+ end
66
+ end
67
+ end
@@ -0,0 +1,28 @@
1
+ require "sports_data_api"
2
+
3
+ # This file was generated by the `rspec --init` command. Conventionally, all
4
+ # specs live under a `spec` directory, which RSpec adds to the `$LOAD_PATH`.
5
+ # Require this file using `require "spec_helper"` to ensure that it is only
6
+ # loaded once.
7
+ #
8
+ # See http://rubydoc.info/gems/rspec-core/RSpec/Core/Configuration
9
+
10
+ def load_xml(filename)
11
+ File.read("#{File.dirname(__FILE__)}/xml/#{filename}.xml")
12
+ end
13
+
14
+ def schedule_xml
15
+ load_xml("schedule")
16
+ end
17
+
18
+ RSpec.configure do |config|
19
+ config.treat_symbols_as_metadata_keys_with_true_values = true
20
+ config.run_all_when_everything_filtered = true
21
+ config.filter_run :focus
22
+
23
+ # Run specs in random order to surface order dependencies. If you find an
24
+ # order dependency and want to debug it, you can fix the order by providing
25
+ # the seed, which is printed after each run.
26
+ # --seed 1234
27
+ config.order = 'random'
28
+ end
data/spec/xml/game.xml ADDED
@@ -0,0 +1,69 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <!-- Generation started at Fri Nov 02 02:27:02 +0000 2012 -->
3
+ <game xmlns="http://feed.elasticstats.com/schema/nfl/boxscore-v1.0.xsd" id="82748625-c24e-437a-b991-cab7f766c249" scheduled="2012-11-02T00:20:00+00:00" home="SD" away="KC" status="inprogress" quarter="3" clock=":53">
4
+ <team id="SD" name="Chargers" market="San Diego" remaining_challenges="2" remaining_timeouts="3">
5
+ <scoring points="10">
6
+ <quarter number="1" points="7"/>
7
+ <quarter number="2" points="3"/>
8
+ <quarter number="3" points="0"/>
9
+ </scoring>
10
+ </team>
11
+ <team id="KC" name="Chiefs" market="Kansas City" remaining_challenges="2" remaining_timeouts="3">
12
+ <scoring points="6">
13
+ <quarter number="1" points="0"/>
14
+ <quarter number="2" points="3"/>
15
+ <quarter number="3" points="3"/>
16
+ </scoring>
17
+ </team>
18
+ <scoring_drives>
19
+ <drive sequence="1" clock="15:00" quarter="1" team="SD">
20
+ <score type="touchdown" clock="10:31" quarter="1" points="6">
21
+ <summary>
22
+ <![CDATA[17-P.Rivers complete to 85-A.Gates. 85-A.Gates runs 14 yards for a touchdown.]]>
23
+ </summary>
24
+ <links>
25
+ <link rel="summary" href="/2012/REG/9/KC/SD/plays/fb5c3b6f-be0a-4f3f-819e-f1134204e312.xml" type="application/xml"/>
26
+ </links>
27
+ </score>
28
+ <score type="extrapoint" clock="10:24" quarter="1" points="1">
29
+ <summary>
30
+ <![CDATA[9-N.Novak extra point is good.]]>
31
+ </summary>
32
+ <links>
33
+ <link rel="summary" href="/2012/REG/9/KC/SD/plays/cecb31f7-febb-470d-b833-b32b9411fa95.xml" type="application/xml"/>
34
+ </links>
35
+ </score>
36
+ </drive>
37
+ <drive sequence="2" clock="02:18" quarter="1" team="SD">
38
+ <score type="fieldgoal" clock="09:13" quarter="2" points="3">
39
+ <summary>
40
+ <![CDATA[9-N.Novak 25 yards Field Goal is Good.]]>
41
+ </summary>
42
+ <links>
43
+ <link rel="summary" href="/2012/REG/9/KC/SD/plays/2036be2d-f58b-4290-9e45-2e171c37588e.xml" type="application/xml"/>
44
+ </links>
45
+ </score>
46
+ </drive>
47
+ <drive sequence="3" clock="09:10" quarter="2" team="KC">
48
+ <score type="fieldgoal" clock="02:56" quarter="2" points="3">
49
+ <summary>
50
+ <![CDATA[6-R.Succop 49 yards Field Goal is Good.]]>
51
+ </summary>
52
+ <links>
53
+ <link rel="summary" href="/2012/REG/9/KC/SD/plays/68de7467-99b7-4e87-939d-7dc9b90c0462.xml" type="application/xml"/>
54
+ </links>
55
+ </score>
56
+ </drive>
57
+ <drive sequence="4" clock="07:09" quarter="3" team="KC">
58
+ <score type="fieldgoal" clock=":58" quarter="3" points="3">
59
+ <summary>
60
+ <![CDATA[6-R.Succop 41 yards Field Goal is Good.]]>
61
+ </summary>
62
+ <links>
63
+ <link rel="summary" href="/2012/REG/9/KC/SD/plays/35b31551-62ce-430b-8d1e-4153a1e81483.xml" type="application/xml"/>
64
+ </links>
65
+ </score>
66
+ </drive>
67
+ </scoring_drives>
68
+ </game>
69
+ <!-- Generation finished at Fri Nov 02 02:27:02 +0000 2012 -->