y_fantasy 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.
- checksums.yaml +7 -0
- data/.pryrc +8 -0
- data/.rspec +3 -0
- data/.rubocop.yml +20 -0
- data/.standard.yml +2 -0
- data/CHANGELOG.md +5 -0
- data/CODE_OF_CONDUCT.md +3 -0
- data/Gemfile +5 -0
- data/Gemfile.lock +220 -0
- data/LICENSE.txt +21 -0
- data/README.md +41 -0
- data/Rakefile +12 -0
- data/exe/y_fantasy +9 -0
- data/lib/y_fantasy/api/authentication.rb +177 -0
- data/lib/y_fantasy/api/client.rb +84 -0
- data/lib/y_fantasy/api/subresource_param_builder.rb +138 -0
- data/lib/y_fantasy/api/url_builder.rb +91 -0
- data/lib/y_fantasy/cli.rb +46 -0
- data/lib/y_fantasy/concerns/subresourceable.rb +87 -0
- data/lib/y_fantasy/ref/nfl.rb +57 -0
- data/lib/y_fantasy/resources/base_resource.rb +117 -0
- data/lib/y_fantasy/resources/base_subresource.rb +31 -0
- data/lib/y_fantasy/resources/game/game_week.rb +26 -0
- data/lib/y_fantasy/resources/game/position_type.rb +20 -0
- data/lib/y_fantasy/resources/game.rb +136 -0
- data/lib/y_fantasy/resources/group/settings.rb +53 -0
- data/lib/y_fantasy/resources/group/standings.rb +11 -0
- data/lib/y_fantasy/resources/group.rb +76 -0
- data/lib/y_fantasy/resources/league/scoreboard.rb +12 -0
- data/lib/y_fantasy/resources/league/settings.rb +51 -0
- data/lib/y_fantasy/resources/league/standings.rb +25 -0
- data/lib/y_fantasy/resources/league.rb +187 -0
- data/lib/y_fantasy/resources/pickem_team/pick.rb +31 -0
- data/lib/y_fantasy/resources/pickem_team/week_pick.rb +28 -0
- data/lib/y_fantasy/resources/pickem_team.rb +98 -0
- data/lib/y_fantasy/resources/player/draft_analysis.rb +26 -0
- data/lib/y_fantasy/resources/player/ownership_percentage.rb +26 -0
- data/lib/y_fantasy/resources/player/stat_collection.rb +32 -0
- data/lib/y_fantasy/resources/player.rb +157 -0
- data/lib/y_fantasy/resources/shared_subresources/draft_result.rb +39 -0
- data/lib/y_fantasy/resources/shared_subresources/matchup.rb +61 -0
- data/lib/y_fantasy/resources/shared_subresources/roster_position.rb +38 -0
- data/lib/y_fantasy/resources/shared_subresources/stat.rb +16 -0
- data/lib/y_fantasy/resources/shared_subresources/stat_category.rb +22 -0
- data/lib/y_fantasy/resources/shared_subresources/stat_modifier.rb +10 -0
- data/lib/y_fantasy/resources/shared_subresources/stat_winner.rb +8 -0
- data/lib/y_fantasy/resources/team/manager.rb +23 -0
- data/lib/y_fantasy/resources/team/roster.rb +18 -0
- data/lib/y_fantasy/resources/team/standings.rb +33 -0
- data/lib/y_fantasy/resources/team/stat_collection.rb +38 -0
- data/lib/y_fantasy/resources/team.rb +175 -0
- data/lib/y_fantasy/subresource_validator.rb +67 -0
- data/lib/y_fantasy/transformations/base_transform.rb +62 -0
- data/lib/y_fantasy/transformations/collection_transformer.rb +22 -0
- data/lib/y_fantasy/transformations/default_transformer.rb +22 -0
- data/lib/y_fantasy/transformations/game/position_types_transformer.rb +21 -0
- data/lib/y_fantasy/transformations/game_transformer.rb +54 -0
- data/lib/y_fantasy/transformations/group_transformer.rb +39 -0
- data/lib/y_fantasy/transformations/instantiator.rb +25 -0
- data/lib/y_fantasy/transformations/key_unwrapper.rb +12 -0
- data/lib/y_fantasy/transformations/league/scoreboard_transformer.rb +21 -0
- data/lib/y_fantasy/transformations/league/settings_transformer.rb +25 -0
- data/lib/y_fantasy/transformations/league/standings_transformer.rb +22 -0
- data/lib/y_fantasy/transformations/league_transformer.rb +57 -0
- data/lib/y_fantasy/transformations/matchups_transformer.rb +22 -0
- data/lib/y_fantasy/transformations/pickem_team/week_picks_transformer.rb +29 -0
- data/lib/y_fantasy/transformations/pickem_team_transformer.rb +41 -0
- data/lib/y_fantasy/transformations/player/ownership_percentage_transformer.rb +21 -0
- data/lib/y_fantasy/transformations/player/stats_transformer.rb +32 -0
- data/lib/y_fantasy/transformations/player_transformer.rb +34 -0
- data/lib/y_fantasy/transformations/stat_categories_transformer.rb +19 -0
- data/lib/y_fantasy/transformations/stat_modifiers_transformer.rb +19 -0
- data/lib/y_fantasy/transformations/t.rb +44 -0
- data/lib/y_fantasy/transformations/team/manager_transformer.rb +19 -0
- data/lib/y_fantasy/transformations/team/roster_transformer.rb +27 -0
- data/lib/y_fantasy/transformations/team/standings_transformer.rb +42 -0
- data/lib/y_fantasy/transformations/team/stats_transformer.rb +30 -0
- data/lib/y_fantasy/transformations/team_transformer.rb +54 -0
- data/lib/y_fantasy/transformations/user_transformer.rb +17 -0
- data/lib/y_fantasy/transformations.rb +54 -0
- data/lib/y_fantasy/version.rb +5 -0
- data/lib/y_fantasy.rb +36 -0
- data/sig/y_fantasy.rbs +4 -0
- data/y_fantasy.gemspec +49 -0
- metadata +364 -0
@@ -0,0 +1,138 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module YFantasy
|
4
|
+
module Api
|
5
|
+
class SubresourceParamBuilder
|
6
|
+
SUBRESOURCE_MAP = {
|
7
|
+
draft_results: :draftresults,
|
8
|
+
ownership_percentage: :percent_owned,
|
9
|
+
team_standings: :standings
|
10
|
+
}
|
11
|
+
|
12
|
+
PLAYER_FILTERS = [
|
13
|
+
:count,
|
14
|
+
:position,
|
15
|
+
:search,
|
16
|
+
:sort,
|
17
|
+
:sort_type,
|
18
|
+
:start,
|
19
|
+
:status
|
20
|
+
].freeze
|
21
|
+
|
22
|
+
def initialize(subresources = [], **options)
|
23
|
+
@regular_subs, @nested_subs = normalize_subresources(subresources)
|
24
|
+
@week = options.delete(:week)
|
25
|
+
@player_filters = set_player_filters(options)
|
26
|
+
@options = options
|
27
|
+
end
|
28
|
+
|
29
|
+
def build
|
30
|
+
@params = +""
|
31
|
+
add_regular_subresource_segments
|
32
|
+
add_nested_subresource_segments
|
33
|
+
add_subresource_keys
|
34
|
+
add_week
|
35
|
+
add_player_filters
|
36
|
+
@params
|
37
|
+
end
|
38
|
+
|
39
|
+
private
|
40
|
+
|
41
|
+
def add_regular_subresource_segments
|
42
|
+
return if @regular_subs.none?
|
43
|
+
|
44
|
+
if @regular_subs.one? && @nested_subs.none?
|
45
|
+
@params.concat("/#{@regular_subs.first}")
|
46
|
+
elsif @regular_subs.size > 1 && @regular_subs.include?(:players) && !@player_filters.empty?
|
47
|
+
non_player_subs = @regular_subs.select { |sub| sub != :players }
|
48
|
+
@params.concat(";out=#{non_player_subs.join(",")}").concat("/players")
|
49
|
+
else
|
50
|
+
@params.concat(";out=#{@regular_subs.join(",")}")
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
def add_nested_subresource_segments
|
55
|
+
return if @nested_subs.none?
|
56
|
+
|
57
|
+
if @nested_subs.one?
|
58
|
+
key = @nested_subs.first.keys.first
|
59
|
+
val = @nested_subs.first[key]
|
60
|
+
|
61
|
+
@params.concat("/#{key}")
|
62
|
+
@params.concat("/#{val}") if val.is_a?(Symbol)
|
63
|
+
@params.concat("/#{val.keys.first}/#{val.values.first}") if val.is_a?(Hash)
|
64
|
+
@params.concat(";out=#{val.join(",")}") if val.is_a?(Array)
|
65
|
+
else
|
66
|
+
raise self.class::Error.new("Not possible to construct a URL with 2+ sets of nested subresources: #{@nested_subs}")
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
def add_subresource_keys
|
71
|
+
return unless options_include_subresource_keys?
|
72
|
+
|
73
|
+
@options.each_pair do |k, v|
|
74
|
+
k_str = Transformations::T.pluralize(k.to_s.sub("_keys", ""))
|
75
|
+
if @params.include?("/#{k_str}")
|
76
|
+
@params.sub!(k_str, "#{k_str};#{k}=#{v.join(",")}")
|
77
|
+
end
|
78
|
+
end
|
79
|
+
end
|
80
|
+
|
81
|
+
def options_include_subresource_keys?
|
82
|
+
@options.keys.map(&:to_s).any? { |s| s.end_with?("_keys") }
|
83
|
+
end
|
84
|
+
|
85
|
+
def add_week
|
86
|
+
return if @week.nil?
|
87
|
+
|
88
|
+
case @params
|
89
|
+
when /\/(roster|scoreboard)/
|
90
|
+
@params.sub!(/\/(?<res>roster|scoreboard)/, "/\\k<res>;week=#{@week}")
|
91
|
+
when /\/matchups/
|
92
|
+
@params.sub!("matchups", "matchups;weeks=#{@week}")
|
93
|
+
when /\/stats/
|
94
|
+
@params.sub!("stats", "stats;type=week;week=#{@week}")
|
95
|
+
end
|
96
|
+
end
|
97
|
+
|
98
|
+
def add_player_filters
|
99
|
+
return if @player_filters.empty? || !@params.match?(/players/)
|
100
|
+
|
101
|
+
player_params = +""
|
102
|
+
@player_filters.each { |k, v| player_params.concat(k.to_s, "=", v.to_s, ";") }
|
103
|
+
player_params.slice!(-1)
|
104
|
+
@params.sub!("players", "players;#{player_params}")
|
105
|
+
end
|
106
|
+
|
107
|
+
def set_player_filters(options)
|
108
|
+
options.each_with_object({}) do |(k, v), h|
|
109
|
+
h[k] = v if PLAYER_FILTERS.include?(k)
|
110
|
+
end
|
111
|
+
end
|
112
|
+
|
113
|
+
def normalize_subresources(subs)
|
114
|
+
@regular_subs = []
|
115
|
+
@nested_subs = []
|
116
|
+
|
117
|
+
subs.each do |sub|
|
118
|
+
if sub.is_a?(Symbol)
|
119
|
+
@regular_subs << (SUBRESOURCE_MAP[sub] || sub)
|
120
|
+
end
|
121
|
+
|
122
|
+
if sub.is_a?(Hash)
|
123
|
+
sub.each_pair do |key, nested_subs|
|
124
|
+
nested_subs = Transformations::T.wrap_in_array(nested_subs)
|
125
|
+
nested_subs = nested_subs.map { |nested_sub| SUBRESOURCE_MAP[nested_sub] || nested_sub }
|
126
|
+
@nested_subs << (nested_subs.one? ? {key => nested_subs.first} : {key => nested_subs})
|
127
|
+
end
|
128
|
+
end
|
129
|
+
end
|
130
|
+
|
131
|
+
[@regular_subs, @nested_subs]
|
132
|
+
end
|
133
|
+
|
134
|
+
class Error < StandardError
|
135
|
+
end
|
136
|
+
end
|
137
|
+
end
|
138
|
+
end
|
@@ -0,0 +1,91 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module YFantasy
|
4
|
+
module Api
|
5
|
+
class UrlBuilder
|
6
|
+
# NOTE: Could also make an id_params method and use it like `league_ids=`
|
7
|
+
# Key example (game_id.l (for league).league_id): <league_key>79.l.31399</league_key>
|
8
|
+
# ID example (last part of key) <league_id>31399</league_id>
|
9
|
+
# valid urls:
|
10
|
+
# /games;game_keys=79/leagues;league_keys=79.l.31399
|
11
|
+
# /games;game_keys=79/leagues;league_ids=31399
|
12
|
+
# /game/79/leagues;league_keys=79.l.31399
|
13
|
+
# /game/79/leagues;league_ids=31399
|
14
|
+
|
15
|
+
# invalid urls:
|
16
|
+
# /games;game_keys=79/league/31399
|
17
|
+
# /games;game_keys=79/league/79.l.31399
|
18
|
+
# /game/79/league/79.l.31399
|
19
|
+
# /game/79/league/31399
|
20
|
+
|
21
|
+
BASE_URL = "https://fantasysports.yahooapis.com/fantasy/v2"
|
22
|
+
CURRENT_USER_URL = "#{BASE_URL}/users;use_login=1"
|
23
|
+
|
24
|
+
def initialize(resource, keys: [], game_codes: [], subresources: [], **options)
|
25
|
+
@options = options
|
26
|
+
@url = options[:scope_to_user] ? CURRENT_USER_URL.dup : BASE_URL.dup
|
27
|
+
@resource = override_resource(resource.to_s)
|
28
|
+
@keys = Array(keys).map(&:to_s)
|
29
|
+
@game_codes = Array(game_codes).map(&:to_s)
|
30
|
+
@subresources = Array(subresources)
|
31
|
+
end
|
32
|
+
|
33
|
+
def build
|
34
|
+
validate_args!
|
35
|
+
singular_resource? ? build_resource_url : build_collection_url
|
36
|
+
return @url if @subresources.empty?
|
37
|
+
|
38
|
+
params = SubresourceParamBuilder.new(@subresources, **@options).build
|
39
|
+
@url.concat(params)
|
40
|
+
end
|
41
|
+
|
42
|
+
private
|
43
|
+
|
44
|
+
def override_resource(resource)
|
45
|
+
return "team" if resource == "pickem_team"
|
46
|
+
return "teams" if resource == "pickem_teams"
|
47
|
+
|
48
|
+
resource
|
49
|
+
end
|
50
|
+
|
51
|
+
def build_resource_url
|
52
|
+
@url.concat("/", @resource, "/", @keys.first)
|
53
|
+
end
|
54
|
+
|
55
|
+
def build_collection_url
|
56
|
+
@url.concat("/", @resource, collection_params)
|
57
|
+
end
|
58
|
+
|
59
|
+
def collection_params
|
60
|
+
if @resource == "games" && !@game_codes.empty?
|
61
|
+
return ";game_codes=#{@game_codes.join(",")}"
|
62
|
+
end
|
63
|
+
|
64
|
+
return "" if @keys.compact.empty?
|
65
|
+
|
66
|
+
";#{singularize(@resource)}_keys=#{@keys.join(",")}"
|
67
|
+
end
|
68
|
+
|
69
|
+
def singular_resource?
|
70
|
+
singularize(@resource) == @resource
|
71
|
+
end
|
72
|
+
|
73
|
+
def singularize(resource)
|
74
|
+
Transformations::T.singularize(resource)
|
75
|
+
end
|
76
|
+
|
77
|
+
def validate_args!
|
78
|
+
if !@game_codes.empty? && !@keys.empty?
|
79
|
+
raise self.class::Error.new("Cannot build URL with both keys and game_codes")
|
80
|
+
end
|
81
|
+
|
82
|
+
if !@game_codes.empty? && @resource != "games"
|
83
|
+
raise self.class::Error.new("`game_codes` can only be used with Games collection")
|
84
|
+
end
|
85
|
+
end
|
86
|
+
|
87
|
+
class Error < StandardError
|
88
|
+
end
|
89
|
+
end
|
90
|
+
end
|
91
|
+
end
|
@@ -0,0 +1,46 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "thor"
|
4
|
+
|
5
|
+
module YFantasy
|
6
|
+
class CLI < Thor
|
7
|
+
include Thor::Actions
|
8
|
+
|
9
|
+
desc "version", "Prints the YFantasy gem version"
|
10
|
+
def version
|
11
|
+
require "y_fantasy/version"
|
12
|
+
puts YFantasy::VERSION
|
13
|
+
end
|
14
|
+
|
15
|
+
desc "nfl_teams", "Prints Yahoo NFL team information"
|
16
|
+
def nfl_teams
|
17
|
+
require "y_fantasy/ref/nfl"
|
18
|
+
|
19
|
+
YFantasy::Ref::Nfl::TEAM_KEY_MAP.each_with_index do |(key, team), idx|
|
20
|
+
if idx.zero?
|
21
|
+
puts format("%-15s %-15s %-10s %-10s", "City", "Team Name", "Abbrev", "Yahoo Key")
|
22
|
+
puts "-" * 55
|
23
|
+
end
|
24
|
+
puts format("%-15s %-15s %-10s %-10s", team[:city], team[:team_name], team[:abbrev], key)
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
desc "help", "Prints this help message"
|
29
|
+
def help
|
30
|
+
puts self.class.help
|
31
|
+
end
|
32
|
+
|
33
|
+
no_commands do
|
34
|
+
def self.help
|
35
|
+
<<~HELP
|
36
|
+
Usage: y_fantasy [command] [options]
|
37
|
+
|
38
|
+
Commands:
|
39
|
+
version - Prints the YFantasy gem version
|
40
|
+
nfl_teams - Prints Yahoo NFL team information
|
41
|
+
help - Prints this help message
|
42
|
+
HELP
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
@@ -0,0 +1,87 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module YFantasy
|
4
|
+
module Subresourceable
|
5
|
+
def self.included(base)
|
6
|
+
base.include(InstanceMethods)
|
7
|
+
base.extend(ClassMethods)
|
8
|
+
end
|
9
|
+
|
10
|
+
module InstanceMethods
|
11
|
+
def fetched_subresources
|
12
|
+
@fetched_subresources ||= Set.new
|
13
|
+
end
|
14
|
+
|
15
|
+
def add_fetched_subresources(subresources = [])
|
16
|
+
# Using wrap_in_array here because Array() will convert a hash to array
|
17
|
+
Transformations::T.wrap_in_array(subresources).each do |subresource|
|
18
|
+
case subresource
|
19
|
+
when Symbol
|
20
|
+
fetched_subresources << subresource
|
21
|
+
when Hash
|
22
|
+
key = subresource.keys.first
|
23
|
+
fetched_subresources << key
|
24
|
+
sub_instances = Transformations::T.wrap_in_array(send(key))
|
25
|
+
sub_instances&.each do |sub_instance|
|
26
|
+
sub_instance.add_fetched_subresources(subresource[key])
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
module ClassMethods
|
34
|
+
# TODO: may not need these first 3 methods if the subresource_tree works the way I want it to
|
35
|
+
def primary_subresources
|
36
|
+
@primary_subresources ||= []
|
37
|
+
end
|
38
|
+
|
39
|
+
def dependent_subresources
|
40
|
+
@dependent_subresources ||= []
|
41
|
+
end
|
42
|
+
|
43
|
+
def subresources
|
44
|
+
primary_subresources | dependent_subresources
|
45
|
+
end
|
46
|
+
|
47
|
+
def has_subresource(sub, klass:)
|
48
|
+
check_inheritance # This smells
|
49
|
+
klass.dependent? ? (dependent_subresources << sub) : (primary_subresources << sub)
|
50
|
+
add_to_subresource_tree(sub, klass)
|
51
|
+
|
52
|
+
define_method(sub) do
|
53
|
+
ivar = :"@#{sub}"
|
54
|
+
value = instance_variable_get(ivar)
|
55
|
+
return value if (value && value != []) || fetched_subresources.include?(sub)
|
56
|
+
|
57
|
+
value = instance_variable_set(ivar, self.class.fetch_subresource(key, sub))
|
58
|
+
add_fetched_subresources(sub)
|
59
|
+
value
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
def fetch_subresource(key, subresource)
|
64
|
+
resource = find(key, with: [subresource])
|
65
|
+
resource.send(subresource)
|
66
|
+
end
|
67
|
+
|
68
|
+
def add_to_subresource_tree(subresource, klass)
|
69
|
+
@subresource_tree ||= {}
|
70
|
+
@subresource_tree[subresource] = klass.subresources
|
71
|
+
end
|
72
|
+
|
73
|
+
def subresource_tree
|
74
|
+
@subresource_tree || {}
|
75
|
+
end
|
76
|
+
|
77
|
+
def check_inheritance
|
78
|
+
return if superclass == YFantasy::BaseResource || superclass == YFantasy::BaseSubresource
|
79
|
+
|
80
|
+
raise YFantasy::Subresourceable::Error.new("#{self} does not inherit from BaseResource")
|
81
|
+
end
|
82
|
+
end
|
83
|
+
|
84
|
+
class Error < StandardError
|
85
|
+
end
|
86
|
+
end
|
87
|
+
end
|
@@ -0,0 +1,57 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module YFantasy
|
4
|
+
module Ref
|
5
|
+
module Nfl
|
6
|
+
TEAM_KEY_MAP = {
|
7
|
+
"nfl.t.1": {key: "nfl.t.1", abbrev: "atl", city: "Atlanta", team_name: "Falcons"},
|
8
|
+
"nfl.t.2": {key: "nfl.t.2", abbrev: "buf", city: "Buffalo", team_name: "Bills"},
|
9
|
+
"nfl.t.3": {key: "nfl.t.3", abbrev: "chi", city: "Chicago", team_name: "Bears"},
|
10
|
+
"nfl.t.4": {key: "nfl.t.4", abbrev: "cin", city: "Cincinnati", team_name: "Bengals"},
|
11
|
+
"nfl.t.5": {key: "nfl.t.5", abbrev: "cle", city: "Cleveland", team_name: "Browns"},
|
12
|
+
"nfl.t.6": {key: "nfl.t.6", abbrev: "dal", city: "Dallas", team_name: "Cowboys"},
|
13
|
+
"nfl.t.7": {key: "nfl.t.7", abbrev: "den", city: "Denver", team_name: "Broncos"},
|
14
|
+
"nfl.t.8": {key: "nfl.t.8", abbrev: "det", city: "Detroit", team_name: "Lions"},
|
15
|
+
"nfl.t.9": {key: "nfl.t.9", abbrev: "gb", city: "Green Bay", team_name: "Packers"},
|
16
|
+
"nfl.t.10": {key: "nfl.t.10", abbrev: "ten", city: "Tennessee", team_name: "Titans"},
|
17
|
+
"nfl.t.11": {key: "nfl.t.11", abbrev: "ind", city: "Indianapolis", team_name: "Colts"},
|
18
|
+
"nfl.t.12": {key: "nfl.t.12", abbrev: "kc", city: "Kansas City", team_name: "Chiefs"},
|
19
|
+
"nfl.t.13": {key: "nfl.t.13", abbrev: "lv", city: "Las Vegas", team_name: "Rakeyers"},
|
20
|
+
"nfl.t.14": {key: "nfl.t.14", abbrev: "lar", city: "Los Angeles", team_name: "Rams"},
|
21
|
+
"nfl.t.15": {key: "nfl.t.15", abbrev: "mia", city: "Miami", team_name: "Dolphins"},
|
22
|
+
"nfl.t.16": {key: "nfl.t.16", abbrev: "min", city: "Minnesota", team_name: "Vikings"},
|
23
|
+
"nfl.t.17": {key: "nfl.t.17", abbrev: "ne", city: "New England", team_name: "Patriots"},
|
24
|
+
"nfl.t.18": {key: "nfl.t.18", abbrev: "no", city: "New Orleans", team_name: "Saints"},
|
25
|
+
"nfl.t.19": {key: "nfl.t.19", abbrev: "nyg", city: "New York", team_name: "Giants"},
|
26
|
+
"nfl.t.20": {key: "nfl.t.20", abbrev: "nyj", city: "New York", team_name: "Jets"},
|
27
|
+
"nfl.t.21": {key: "nfl.t.21", abbrev: "phi", city: "Philadelphia", team_name: "Eagles"},
|
28
|
+
"nfl.t.22": {key: "nfl.t.22", abbrev: "ari", city: "Arizona", team_name: "Cardinals"},
|
29
|
+
"nfl.t.23": {key: "nfl.t.23", abbrev: "pit", city: "Pittsburgh", team_name: "Steelers"},
|
30
|
+
"nfl.t.24": {key: "nfl.t.24", abbrev: "lac", city: "Los Angeles", team_name: "Chargers"},
|
31
|
+
"nfl.t.25": {key: "nfl.t.25", abbrev: "sf", city: "San Francisco", team_name: "49ers"},
|
32
|
+
"nfl.t.26": {key: "nfl.t.26", abbrev: "sea", city: "Seattle", team_name: "Seahawks"},
|
33
|
+
"nfl.t.27": {key: "nfl.t.27", abbrev: "tb", city: "Tampa Bay", team_name: "Buccaneers"},
|
34
|
+
"nfl.t.28": {key: "nfl.t.28", abbrev: "was", city: "Washington", team_name: "Commanders"},
|
35
|
+
"nfl.t.29": {key: "nfl.t.29", abbrev: "car", city: "Carolina", team_name: "Panthers"},
|
36
|
+
"nfl.t.30": {key: "nfl.t.30", abbrev: "jax", city: "Jacksonville", team_name: "Jaguars"},
|
37
|
+
"nfl.t.33": {key: "nfl.t.33", abbrev: "bal", city: "Baltimore", team_name: "Ravens"},
|
38
|
+
"nfl.t.34": {key: "nfl.t.34", abbrev: "hou", city: "Houston", team_name: "Texans"}
|
39
|
+
}
|
40
|
+
|
41
|
+
def team(key)
|
42
|
+
TEAM_KEY_MAP.fetch(key.to_sym, nil)
|
43
|
+
end
|
44
|
+
module_function :team
|
45
|
+
|
46
|
+
# TODO: Work in progress...
|
47
|
+
STAT_MAP = {
|
48
|
+
0 => "Games Played",
|
49
|
+
8 => "Rush Att",
|
50
|
+
9 => "Rush Yds",
|
51
|
+
11 => "Rec",
|
52
|
+
12 => "Rec Yds",
|
53
|
+
13 => "Rec TD"
|
54
|
+
}
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
@@ -0,0 +1,117 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module YFantasy
|
4
|
+
# @abstract Base class for all "primary" Yahoo Fantasy Sports API resources.
|
5
|
+
# @note Primary resources are those with a Yahoo Key/ID, that can be referenced in a Yahoo Fantasy API URL.
|
6
|
+
# This includes Game, League, Team, Player, Group, and PickemTeam.
|
7
|
+
class BaseResource
|
8
|
+
extend Forwardable
|
9
|
+
extend Dry::Initializer[undefined: false]
|
10
|
+
include Subresourceable
|
11
|
+
|
12
|
+
# Error class for BaseResource exceptions
|
13
|
+
class Error < StandardError
|
14
|
+
end
|
15
|
+
|
16
|
+
# CLASS METHODS
|
17
|
+
class << self
|
18
|
+
# Finds all resources of the current type
|
19
|
+
# @param keys [Array<String, Symbol, Integer>] Keys to find resources by
|
20
|
+
# @param with [Array<Symbol>, Symbol] Subresources to include with the response
|
21
|
+
# @param scope_to_user [Boolean] Whether to scope the request to the authenticated user
|
22
|
+
# @return [Array<BaseResource>] Collection of resources
|
23
|
+
def find_all(keys = [], with: [], scope_to_user: false)
|
24
|
+
keys = Array(keys)
|
25
|
+
subresources = Transformations::T.wrap_in_array(with)
|
26
|
+
data = YFantasy::Api::Client.get(
|
27
|
+
collection_name, keys: keys, subresources: subresources, scope_to_user: scope_to_user
|
28
|
+
)
|
29
|
+
resources = Transformations::CollectionTransformer.new(collection_name).call(data)
|
30
|
+
resources.each { |resource| resource.add_fetched_subresources(subresources) }
|
31
|
+
resources
|
32
|
+
end
|
33
|
+
|
34
|
+
# Finds a single resource by key
|
35
|
+
# @param key [String, Symbol, Integer] The key to find the resource by
|
36
|
+
# @param with [Array<Symbol>, Symbol] Subresources to include with the response
|
37
|
+
# @param options [Hash] Additional options for the request
|
38
|
+
# @return [BaseResource] The requested resource
|
39
|
+
# @raise [Error] If invalid options are provided
|
40
|
+
def find(key, with: [], **options)
|
41
|
+
validate_options(options)
|
42
|
+
subresources = Transformations::T.wrap_in_array(with)
|
43
|
+
SubresourceValidator.validate!(self, subresources)
|
44
|
+
# TODO: Remove
|
45
|
+
# puts "\n YFantasy::Api::Client.get('#{resource_name}', '#{key}', #{subresources}, #{options}) \n"
|
46
|
+
|
47
|
+
data = YFantasy::Api::Client.get(resource_name, keys: key, subresources: subresources, **options)
|
48
|
+
resource = Transformations.transformer_for(resource_name).call(data)
|
49
|
+
resource.add_fetched_subresources(subresources)
|
50
|
+
resource
|
51
|
+
end
|
52
|
+
|
53
|
+
# Always returns false for primary resources (anything that inherits from BaseResource)
|
54
|
+
# @return [Boolean] False by default.
|
55
|
+
def dependent?
|
56
|
+
false
|
57
|
+
end
|
58
|
+
|
59
|
+
# Returns the resource name as a symbol
|
60
|
+
# @return [Symbol, nil] The resource name or nil if this is the BaseResource
|
61
|
+
def resource_name
|
62
|
+
return if base_resource?
|
63
|
+
|
64
|
+
to_s.split("::").last.scan(/[A-Z][a-z]+/).join("_").downcase.to_sym
|
65
|
+
end
|
66
|
+
|
67
|
+
# Returns the collection name (aka pluralized resource name)
|
68
|
+
# @return [Symbol, nil] The collection name or nil if this is the BaseResource
|
69
|
+
def collection_name
|
70
|
+
return if base_resource?
|
71
|
+
|
72
|
+
:"#{resource_name}s"
|
73
|
+
end
|
74
|
+
|
75
|
+
private
|
76
|
+
|
77
|
+
# Determines if this is the base resource class
|
78
|
+
# @return [Boolean] True if this is the BaseResource class
|
79
|
+
def base_resource?
|
80
|
+
self == YFantasy::BaseResource
|
81
|
+
end
|
82
|
+
|
83
|
+
# Creates a transformer that instantiates a single object of the given class
|
84
|
+
# @param klass [Class] The class to instantiate
|
85
|
+
# @return [Transformations::Instantiator] A transformer that instantiates the class
|
86
|
+
def instance_of(klass)
|
87
|
+
Transformations::Instantiator.new(klass)
|
88
|
+
end
|
89
|
+
|
90
|
+
# Creates a transformer that instantiates an array of objects of the given class
|
91
|
+
# @param klass [Class] The class to instantiate
|
92
|
+
# @return [Transformations::Instantiator] A transformer that instantiates an array of the class
|
93
|
+
def array_of(klass)
|
94
|
+
Transformations::Instantiator.new(klass, collection: true)
|
95
|
+
end
|
96
|
+
|
97
|
+
# Validates options hash for API requests
|
98
|
+
# @param options [Hash] Options hash to validate
|
99
|
+
# @raise [Error] If invalid options are provided
|
100
|
+
def validate_options(options)
|
101
|
+
return unless options[:scope_to_user]
|
102
|
+
|
103
|
+
raise Error.new("`scope_to_user` is not valid when requesting a single resource. Use `.find_all`.")
|
104
|
+
end
|
105
|
+
end
|
106
|
+
|
107
|
+
# INSTANCE METHODS
|
108
|
+
|
109
|
+
# Returns the key of the resource
|
110
|
+
# @return [Object, nil] The resource key or nil if not applicable
|
111
|
+
def key
|
112
|
+
if (name = self.class.resource_name)
|
113
|
+
public_send(:"#{name}_key")
|
114
|
+
end
|
115
|
+
end
|
116
|
+
end
|
117
|
+
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module YFantasy
|
4
|
+
class BaseSubresource
|
5
|
+
extend Dry::Initializer[undefined: false]
|
6
|
+
include Subresourceable
|
7
|
+
|
8
|
+
class << self
|
9
|
+
def dependent?
|
10
|
+
true
|
11
|
+
end
|
12
|
+
|
13
|
+
def resource_name
|
14
|
+
return if self == YFantasy::BaseSubresource
|
15
|
+
|
16
|
+
to_s.split("::").last.scan(/[A-Z][a-z]+/).join("_").downcase.to_sym
|
17
|
+
end
|
18
|
+
|
19
|
+
def find(resource_name, key)
|
20
|
+
data = YFantasy::Api::Client.get(resource_name, keys: key)
|
21
|
+
Transformations.transformer_for(resource_name).call(data)
|
22
|
+
end
|
23
|
+
|
24
|
+
private
|
25
|
+
|
26
|
+
def array_of(klass)
|
27
|
+
Transformations::Instantiator.new(klass, collection: true)
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module YFantasy
|
4
|
+
class Game
|
5
|
+
# Represents a week in a fantasy game schedule
|
6
|
+
class GameWeek < BaseSubresource
|
7
|
+
# --- REQUIRED ATTRIBUTES ----------------------------------------------------------------------------------------
|
8
|
+
|
9
|
+
# @!attribute [r] week
|
10
|
+
# @return [Integer] the week number
|
11
|
+
option :week, type: Types::Coercible::Integer
|
12
|
+
|
13
|
+
# @!attribute [r] display_name
|
14
|
+
# @return [String] the week number as a string
|
15
|
+
option :display_name
|
16
|
+
|
17
|
+
# @!attribute [r] start
|
18
|
+
# @return [Date] week start date
|
19
|
+
option :start, type: Types::Params::Date
|
20
|
+
|
21
|
+
# @!attribute [r] end
|
22
|
+
# @return [Date] week end date
|
23
|
+
option :end, type: Types::Params::Date
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module YFantasy
|
4
|
+
class Game
|
5
|
+
# Represents a position type within a fantasy game
|
6
|
+
class PositionType < BaseSubresource
|
7
|
+
# --- REQUIRED ATTRIBUTES ----------------------------------------------------------------------------------------
|
8
|
+
|
9
|
+
# @!attribute [r] type
|
10
|
+
# @return [String] position type abbreviation
|
11
|
+
# @example "O", "K", "DT"
|
12
|
+
option :type
|
13
|
+
|
14
|
+
# @!attribute [r] display_name
|
15
|
+
# @return [String] full name of the position type
|
16
|
+
# @example "Offense", "Kickers", "Defense/Special Teams"
|
17
|
+
option :display_name
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|