foot_stats 0.0.1 → 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.
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