foot_stats 0.0.1 → 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
data/README.md CHANGED
@@ -20,10 +20,11 @@ Or install it yourself as:
20
20
 
21
21
  ```ruby
22
22
  FootStats::Setup.setup do |config|
23
- config.username = "username"
24
- config.password = "password"
25
- config.logger = Rails.logger
26
- config.base_url = "http://footstats.com"
23
+ config.username = "username"
24
+ config.password = "password"
25
+ config.logger = Rails.logger
26
+ config.base_url = "http://footstats.com"
27
+ config.payload_store = Redis.new
27
28
  end
28
29
  ```
29
30
 
@@ -60,7 +61,6 @@ Or install it yourself as:
60
61
 
61
62
  ## Next
62
63
 
63
- * LIVE 'feed'.
64
64
  * Create a Fake App (Sandbox), that simulates FootStats API.
65
65
 
66
66
  ## Contributing
@@ -17,10 +17,13 @@ Gem::Specification.new do |gem|
17
17
  gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
18
18
  gem.require_paths = ["lib"]
19
19
 
20
- gem.add_dependency 'activesupport'
20
+ gem.add_dependency 'json'
21
+ gem.add_dependency 'redis'
22
+ gem.add_dependency 'redis-namespace'
21
23
  gem.add_dependency 'rest-client'
22
24
 
23
- gem.add_development_dependency 'rspec'
24
25
  gem.add_development_dependency 'vcr'
26
+ gem.add_development_dependency 'rake'
27
+ gem.add_development_dependency 'rspec'
25
28
  gem.add_development_dependency 'fakeweb'
26
29
  end
@@ -1,14 +1,25 @@
1
+ require 'singleton'
2
+ require 'digest/md5'
3
+
4
+ require 'json'
5
+ require 'rest-client'
6
+
1
7
  require 'foot_stats/version'
2
8
 
3
9
  module FootStats
4
- autoload :Championship, 'foot_stats/championship'
10
+ autoload :AttributeAccessor, 'foot_stats/attribute_accessor'
11
+ autoload :Championship, 'foot_stats/championship'
5
12
  autoload :ChampionshipClassification, 'foot_stats/championship_classification'
6
- autoload :ErrorResponse, 'foot_stats/error_response'
7
- autoload :Match, 'foot_stats/match'
8
- autoload :Narration, 'foot_stats/narration'
9
- autoload :Resource, 'foot_stats/resource'
10
- autoload :Request, 'foot_stats/request'
11
- autoload :Response, 'foot_stats/response'
12
- autoload :Team, 'foot_stats/team'
13
- autoload :Setup, 'foot_stats/setup'
13
+ autoload :ErrorResponse, 'foot_stats/error_response'
14
+ autoload :Live, 'foot_stats/live'
15
+ autoload :Match, 'foot_stats/match'
16
+ autoload :Narration, 'foot_stats/narration'
17
+ autoload :Player, 'foot_stats/player'
18
+ autoload :Request, 'foot_stats/request'
19
+ autoload :Resource, 'foot_stats/resource'
20
+ autoload :Response, 'foot_stats/response'
21
+ autoload :RoundMatch, 'foot_stats/round_match'
22
+ autoload :Setup, 'foot_stats/setup'
23
+ autoload :Stream, 'foot_stats/stream'
24
+ autoload :Team, 'foot_stats/team'
14
25
  end
@@ -0,0 +1,24 @@
1
+ module FootStats
2
+ module AttributeAccessor
3
+ def self.included(base)
4
+ base.extend(ClassMethods)
5
+ end
6
+
7
+ def attributes
8
+ attrs = Hash.new
9
+ self.class.attributes.each{ |attribute| attrs[attribute] = send attribute }
10
+ attrs
11
+ end
12
+
13
+ module ClassMethods
14
+ def attributes
15
+ @attributes ||= []
16
+ end
17
+
18
+ def attribute_accessor(*attrs)
19
+ self.attributes.concat attrs
20
+ attr_accessor *attrs
21
+ end
22
+ end
23
+ end
24
+ end
@@ -1,17 +1,20 @@
1
1
  module FootStats
2
2
  class Championship < Resource
3
- attr_accessor :source_id, :name, :has_classification, :current_round, :total_rounds
3
+ attribute_accessor :source_id, :name, :has_classification, :current_round, :total_rounds
4
4
 
5
5
  # Retrieve all championships from FootStats
6
6
  #
7
7
  # @return [Array]
8
8
  #
9
- def self.all
10
- request = Request.new(self)
11
- response = request.parse
9
+ def self.all(options = {})
10
+ response = Request.new(self).parse stream_key: 'championships'
12
11
 
13
12
  return response.error if response.error?
14
13
 
14
+ updated_response response, options
15
+ end
16
+
17
+ def self.parse_response(response)
15
18
  response.collect do |championship|
16
19
  new(
17
20
  :source_id => championship['@Id'].to_i,
@@ -43,24 +46,24 @@ module FootStats
43
46
  #
44
47
  # @return [Array]
45
48
  #
46
- def classification
47
- ChampionshipClassification.all(championship: source_id)
49
+ def classification(options = {})
50
+ ChampionshipClassification.all(options.merge(championship: source_id))
48
51
  end
49
52
 
50
53
  # Return the Championship teams.
51
54
  #
52
55
  # @return [Array]
53
56
  #
54
- def teams
55
- Team.all(championship: source_id)
57
+ def teams(options = {})
58
+ Team.all(options.merge(championship: source_id))
56
59
  end
57
60
 
58
61
  # Return all the Championship matches.
59
62
  #
60
63
  # @return [Array]
61
64
  #
62
- def matches
63
- Match.all(championship: source_id)
65
+ def matches(options = {})
66
+ Match.all(options.merge(championship: source_id))
64
67
  end
65
68
  end
66
69
  end
@@ -6,11 +6,16 @@ module FootStats
6
6
  attr_accessor :use
7
7
 
8
8
  def self.all(options={})
9
- request = Request.new(self, :Campeonato => options.fetch(:championship))
10
- response = request.parse
9
+ championship_id = options.fetch(:championship)
10
+ request = Request.new self, :Campeonato => championship_id
11
+ response = request.parse stream_key: "championship-classification-#{championship_id}"
11
12
 
12
13
  return response.error if response.error?
13
14
 
15
+ updated_response response, options
16
+ end
17
+
18
+ def self.parse_response(response)
14
19
  response["Classificacoes"]['Classificacao']['Equipe'].collect do |classification|
15
20
  ChampionshipClassification.new(
16
21
  :team_source_id => classification['@Id'].to_i,
@@ -0,0 +1,120 @@
1
+ module FootStats
2
+ class Live < Resource
3
+ autoload :Card, 'foot_stats/live_card'
4
+ autoload :Goal, 'foot_stats/live_goal'
5
+ autoload :Player, 'foot_stats/live_player'
6
+ autoload :Team, 'foot_stats/live_team'
7
+
8
+ MAPPED_PARAMS = {
9
+ source_id: '@IdPartida',
10
+ score: '@Placar',
11
+ penalty_score: '@PlacarPenaltis',
12
+ date: '@Data',
13
+ period: '@Periodo',
14
+ referee: '@Arbitro',
15
+ stadium: '@Estadio',
16
+ city: '@Cidade',
17
+ country: '@Pais',
18
+ has_narration: '@TemNarracao',
19
+ round: '@Rodada',
20
+ phase: '@Fase',
21
+ cup: '@Taca',
22
+ group: '@Grupo',
23
+ home_team: 'Mandante',
24
+ visitor_team: 'Visitante'
25
+ }
26
+
27
+ attr_accessor *MAPPED_PARAMS.keys
28
+
29
+ alias :narration? :has_narration
30
+
31
+ def home_score
32
+ score[:home]
33
+ end
34
+
35
+ def visitor_score
36
+ score[:visitor]
37
+ end
38
+
39
+ def home_penalty_score
40
+ penalty_score[:home]
41
+ end
42
+
43
+ def visitor_penalty_score
44
+ penalty_score[:visitor]
45
+ end
46
+
47
+ alias :narration? :has_narration
48
+
49
+ class << self
50
+ # Retrieve live data of a match
51
+ #
52
+ # @return [Live]
53
+ #
54
+ def find(match_id, options={})
55
+ response = Request.new(self, :IdPartida => match_id).parse stream_key: 'live_match'
56
+ return response.error if response.error?
57
+
58
+ updated_response response, options
59
+ end
60
+
61
+ # Return the resource name to request to FootStats.
62
+ #
63
+ # @return [String]
64
+ #
65
+ def resource_name
66
+ 'AoVivo'
67
+ end
68
+
69
+ # Return the resource key that is fetch from the API response.
70
+ #
71
+ # @return [String]
72
+ #
73
+ def resource_key
74
+ nil
75
+ end
76
+
77
+ protected
78
+ def parse_response(response)
79
+ live_params = Hash.new
80
+
81
+ MAPPED_PARAMS.each do |key, foot_stats_key|
82
+ setter_method = :"parse_#{key}"
83
+ if respond_to? setter_method
84
+ live_params[key] = send setter_method, response[foot_stats_key]
85
+ else
86
+ live_params[key] = response[foot_stats_key]
87
+ end
88
+ end
89
+
90
+ self.new live_params
91
+ end
92
+
93
+ def parse_int(value)
94
+ value.to_i
95
+ end
96
+ alias :parse_source_id :parse_int
97
+ alias :parse_round :parse_int
98
+
99
+ def parse_score(score)
100
+ home_score, visitor_score = score.split '-'
101
+ {
102
+ home: (home_score || 0).to_i,
103
+ visitor: (visitor_score || 0).to_i
104
+ }
105
+ end
106
+ alias :parse_penalty_score :parse_score
107
+
108
+ def parse_has_narration(narration)
109
+ narration == 'Sim'
110
+ end
111
+
112
+ def parse_team(team_params)
113
+ Team.new team_params
114
+ end
115
+ alias :parse_home_team :parse_team
116
+ alias :parse_visitor_team :parse_team
117
+
118
+ end
119
+ end
120
+ end
@@ -0,0 +1,14 @@
1
+ module FootStats
2
+ class Live < Resource
3
+ class Card
4
+ attr_reader :player_name, :period, :minute, :type
5
+
6
+ def initialize(params)
7
+ @player_name = params['@Jogador']
8
+ @period = params['@Periodo']
9
+ @minute = params['@Minuto'].to_i
10
+ @type = params['@Tipo']
11
+ end
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,14 @@
1
+ module FootStats
2
+ class Live < Resource
3
+ class Goal
4
+ attr_reader :player_name, :period, :minute, :type
5
+
6
+ def initialize(params)
7
+ @player_name = params['@Jogador']
8
+ @period = params['@Periodo']
9
+ @minute = params['@Minuto'].to_i
10
+ @type = params['@Tipo']
11
+ end
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,28 @@
1
+ module FootStats
2
+ class Live < Resource
3
+ class Player
4
+ attr_reader :source_id, :name, :status, :was_substituted, :substituted, :period, :minute
5
+
6
+ def initialize(params)
7
+ @source_id = params["@IdJogador"].to_i
8
+ @name = params["@Jogador"]
9
+ @status = params["@Status"]
10
+ @was_substituted = params["@Substituto"] != ''
11
+ @period = params["@Periodo"]
12
+ @minute = params["@Minuto"].to_i
13
+
14
+ @substituted = params["@Substituto"] if @was_substituted
15
+ end
16
+
17
+ alias :substituted? :was_substituted
18
+
19
+ def self.diff(players, old_players_ids)
20
+ new_players_ids = players.map &:source_id
21
+ {
22
+ added: (new_players_ids - old_players_ids),
23
+ removed: (old_players_ids - new_players_ids)
24
+ }
25
+ end
26
+ end
27
+ end
28
+ end
@@ -0,0 +1,55 @@
1
+ module FootStats
2
+ class Live < Resource
3
+ class Team
4
+ attr_reader :coach, :full_name, :source_id
5
+ attr_reader :cards, :players, :goals
6
+
7
+ def initialize(params)
8
+ @coach = params['@Tecnico']
9
+ @full_name = params['@Nome']
10
+ @source_id = params['@Id']
11
+
12
+ parse_cards params['Cartoes']
13
+ parse_goals params['Gols']
14
+ parse_players params['Escalacao']
15
+ end
16
+
17
+ def initial_players
18
+ players.find_all{ |player| !player.substituted? }
19
+ end
20
+
21
+ def substituted_players
22
+ players.find_all{ |player| player.substituted? }
23
+ end
24
+
25
+ protected
26
+ def fix_collection(collection, key)
27
+ return [] if collection.nil?
28
+
29
+ if collection[key].is_a? Array
30
+ collection[key]
31
+ else
32
+ [ collection[key] ]
33
+ end
34
+ end
35
+
36
+ def parse_goals(goals)
37
+ @goals = fix_collection(goals, 'Gol').map do |goal_params|
38
+ Goal.new goal_params
39
+ end
40
+ end
41
+
42
+ def parse_cards(cards)
43
+ @cards = fix_collection(cards, 'Cartoes').map do |card_params|
44
+ Card.new card_params
45
+ end
46
+ end
47
+
48
+ def parse_players(players)
49
+ @players = fix_collection(players, 'Jogador').map do |player_params|
50
+ Player.new player_params
51
+ end
52
+ end
53
+ end
54
+ end
55
+ end
@@ -1,17 +1,22 @@
1
1
  module FootStats
2
2
  class Match < Resource
3
- attr_accessor :source_id, :date, :status, :referee, :stadium, :city, :state
4
- attr_accessor :country, :has_statistic, :has_narration, :round, :phase
5
- attr_accessor :cup, :group, :game_number, :live
6
- attr_accessor :home_team, :home_team_name, :home_score, :home_penalties_score
7
- attr_accessor :visitor_team, :visitor_team_name, :visitor_score, :visitor_penalties_score
3
+ attribute_accessor :source_id, :date, :status, :referee, :stadium, :city, :state
4
+ attribute_accessor :country, :has_statistic, :has_narration, :round, :phase
5
+ attribute_accessor :cup, :group, :game_number, :live
6
+ attribute_accessor :home_team, :home_team_name, :home_score, :home_penalties_score
7
+ attribute_accessor :visitor_team, :visitor_team_name, :visitor_score, :visitor_penalties_score
8
8
 
9
9
  def self.all(options={})
10
- request = Request.new(self, :Campeonato => options.fetch(:championship))
11
- response = request.parse
10
+ championship_id = options.fetch(:championship)
11
+ request = Request.new self, :Campeonato => options.fetch(:championship)
12
+ response = request.parse stream_key: "match_championship-#{championship_id}"
12
13
 
13
14
  return response.error if response.error?
14
15
 
16
+ updated_response response, options
17
+ end
18
+
19
+ def self.parse_response(response)
15
20
  response['Partida'].collect do |match|
16
21
  match_object = Match.new(
17
22
  :source_id => match['@Id'].to_i,
@@ -70,8 +75,36 @@ module FootStats
70
75
  #
71
76
  # @return [Array]
72
77
  #
73
- def narrations
74
- Narration.all(match: source_id)
78
+ def narrations(options = {})
79
+ Narration.all(options.merge(match: source_id))
80
+ end
81
+
82
+ # Return live date of a match
83
+ #
84
+ # @return [Live]
85
+ #
86
+ def live(options = {})
87
+ Live.find source_id, options
88
+ end
89
+
90
+ # Live setter
91
+ #
92
+ # @return [boolean]
93
+ #
94
+ def live=(value)
95
+ if value == 'Sim' || value == true
96
+ @has_live = true
97
+ else
98
+ @has_live = false
99
+ end
100
+ end
101
+
102
+ # Checks if match has live coverage
103
+ #
104
+ # @return [boolean]
105
+ #
106
+ def live?
107
+ @has_live
75
108
  end
76
109
  end
77
110
  end