blizzard_api 0.6.2 → 2.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (56) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +25 -0
  3. data/Gemfile.lock +12 -14
  4. data/blizzard_api.gemspec +0 -1
  5. data/lib/blizzard_api/api_standards.rb +55 -0
  6. data/lib/blizzard_api/configuration.rb +20 -17
  7. data/lib/blizzard_api/diablo/community/profile.rb +4 -4
  8. data/lib/blizzard_api/diablo/game_data/generic_data_endpoint.rb +2 -2
  9. data/lib/blizzard_api/diablo/request.rb +3 -3
  10. data/lib/blizzard_api/diablo.rb +33 -27
  11. data/lib/blizzard_api/hearthstone/game_data/generic_data_endpoint.rb +2 -2
  12. data/lib/blizzard_api/hearthstone/request.rb +3 -3
  13. data/lib/blizzard_api/hearthstone.rb +18 -12
  14. data/lib/blizzard_api/request.rb +27 -76
  15. data/lib/blizzard_api/starcraft/community/account.rb +1 -1
  16. data/lib/blizzard_api/starcraft/community/legacy.rb +6 -6
  17. data/lib/blizzard_api/starcraft/request.rb +3 -3
  18. data/lib/blizzard_api/starcraft.rb +20 -14
  19. data/lib/blizzard_api/token_manager.rb +49 -0
  20. data/lib/blizzard_api/version.rb +1 -1
  21. data/lib/blizzard_api/wow/game_data/achievement.rb +1 -16
  22. data/lib/blizzard_api/wow/game_data/azerite_essence.rb +2 -9
  23. data/lib/blizzard_api/wow/game_data/connected_realm.rb +1 -8
  24. data/lib/blizzard_api/wow/game_data/covenant.rb +2 -9
  25. data/lib/blizzard_api/wow/game_data/creature.rb +2 -13
  26. data/lib/blizzard_api/wow/game_data/generic_data_endpoint.rb +10 -37
  27. data/lib/blizzard_api/wow/game_data/guild_crest.rb +4 -10
  28. data/lib/blizzard_api/wow/game_data/item.rb +3 -18
  29. data/lib/blizzard_api/wow/game_data/journal.rb +2 -17
  30. data/lib/blizzard_api/wow/game_data/media.rb +2 -13
  31. data/lib/blizzard_api/wow/game_data/modified_crafting.rb +1 -12
  32. data/lib/blizzard_api/wow/game_data/mount.rb +1 -8
  33. data/lib/blizzard_api/wow/game_data/mythic_keystone.rb +2 -13
  34. data/lib/blizzard_api/wow/game_data/mythic_keystone_affix.rb +2 -9
  35. data/lib/blizzard_api/wow/game_data/pet.rb +2 -9
  36. data/lib/blizzard_api/wow/game_data/playable_class.rb +2 -48
  37. data/lib/blizzard_api/wow/game_data/playable_race.rb +1 -8
  38. data/lib/blizzard_api/wow/game_data/playable_specialization.rb +1 -18
  39. data/lib/blizzard_api/wow/game_data/power_type.rb +1 -8
  40. data/lib/blizzard_api/wow/game_data/profession.rb +2 -9
  41. data/lib/blizzard_api/wow/game_data/pvp_region.rb +82 -0
  42. data/lib/blizzard_api/wow/game_data/pvp_season.rb +7 -9
  43. data/lib/blizzard_api/wow/game_data/pvp_tier.rb +3 -10
  44. data/lib/blizzard_api/wow/game_data/quest.rb +2 -9
  45. data/lib/blizzard_api/wow/game_data/realm.rb +1 -8
  46. data/lib/blizzard_api/wow/game_data/region.rb +1 -8
  47. data/lib/blizzard_api/wow/game_data/reputation.rb +2 -9
  48. data/lib/blizzard_api/wow/game_data/spell.rb +2 -17
  49. data/lib/blizzard_api/wow/game_data/talent.rb +2 -9
  50. data/lib/blizzard_api/wow/game_data/tech_talent.rb +2 -9
  51. data/lib/blizzard_api/wow/game_data/title.rb +1 -16
  52. data/lib/blizzard_api/wow/profile/profile.rb +3 -3
  53. data/lib/blizzard_api/wow/request.rb +3 -3
  54. data/lib/blizzard_api/wow.rb +122 -108
  55. data/lib/blizzard_api.rb +9 -0
  56. metadata +5 -16
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 4e14a76f532abc2360a9a74e693193e472d79ea0749536d0403a8981d6845db4
4
- data.tar.gz: 8495ff7e71e1363babfcd25b7b27c841984e186609853103c243313eeaaeecec
3
+ metadata.gz: 96579c93bc977c1e27958031f03956a7fd19a1c54507a792a8c40fad27c24aea
4
+ data.tar.gz: b0947d10581d4324503e561dc07059c2fc35f81f27be51b6d322d68abea87064
5
5
  SHA512:
6
- metadata.gz: e20a235281a8b7dbd693e326103d78c8d56b976d6f599fff0bc06751361609a69441d303c49e22a44d041186435a5410eb7c8d106b327e104a9562690932d65b
7
- data.tar.gz: f40d893688257ecfabadf1050b2e65146d03665ca85435b9a9e789f0c1c7dedc7ecc3289bbe077d2ef748cc162a161c12553422f1aa6e0872c6f77881600dd4a
6
+ metadata.gz: 1dcdbfc4de7830373ebfda93f8bca5e2f4acc2743b18a5bcd16c6141574e48e13153966041ee4e699c75c76f9ec6af976f8c59116c0dd47f5445cf74d5aded4f
7
+ data.tar.gz: c2ee55a8fb82065315dc7dc43ff14e6e1e511ffb67984ba57b1983da34d2c94ded0e6a49c46168e129bd991a788bfbe9a8ad4724bd3e7533ca6bd38914a82046
data/CHANGELOG.md CHANGED
@@ -1,5 +1,30 @@
1
1
  Please view this file on the master branch, otherwise it may be outdated
2
2
 
3
+ **Version 2.0.0**
4
+
5
+ Removed the `icon` field from PlayableClass, it was meant to mimic the old communit API behavior during the transition
6
+ to the new game_data version.
7
+
8
+ **Version 1.0.0**
9
+
10
+ Removed the `complete` method from WoW game data endpoints.
11
+ Removed the `concurrency` request and configuration option as it is not necessary anymore.
12
+ Removed the `thwait` dependency.
13
+
14
+ Added the `redis_database` option to support selecting the redis database for caching data.
15
+ The gem will now share a single Redis connection across all calls.
16
+ The gem now creates a new token on demand if the previous one has expired.
17
+ It is now possible to cache the token in Redis to avoid needlessly creating a new token.
18
+ It is now possible to set the default mode for API calls
19
+
20
+ **Version 0.6.4**
21
+
22
+ Fixed argument propagation in SC2 legacy profile methods.
23
+
24
+ **Version 0.6.3**
25
+
26
+ Fixed argument propagation in some profile methods.
27
+
3
28
  **Version 0.6.2**
4
29
 
5
30
  Fixed an encoding problem on search endpoints.
data/Gemfile.lock CHANGED
@@ -1,24 +1,22 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- blizzard_api (0.6.2)
4
+ blizzard_api (1.0.0)
5
5
  redis (~> 4.1, >= 4.1.0)
6
- thwait (~> 0.2.0)
7
6
 
8
7
  GEM
9
8
  remote: https://rubygems.org/
10
9
  specs:
11
10
  ast (2.4.2)
12
11
  dotenv (2.7.6)
13
- e2mmap (0.1.0)
14
- minitest (5.14.4)
15
- parallel (1.20.1)
16
- parser (3.0.1.1)
12
+ minitest (5.15.0)
13
+ parallel (1.21.0)
14
+ parser (3.0.3.2)
17
15
  ast (~> 2.4.1)
18
16
  rainbow (3.0.0)
19
- rake (13.0.3)
20
- redis (4.2.5)
21
- regexp_parser (2.1.1)
17
+ rake (13.0.6)
18
+ redis (4.5.1)
19
+ regexp_parser (2.2.0)
22
20
  rexml (3.2.5)
23
21
  rubocop (0.93.1)
24
22
  parallel (~> 1.10)
@@ -29,13 +27,13 @@ GEM
29
27
  rubocop-ast (>= 0.6.0)
30
28
  ruby-progressbar (~> 1.7)
31
29
  unicode-display_width (>= 1.4.0, < 2.0)
32
- rubocop-ast (1.5.0)
30
+ rubocop-ast (1.15.1)
33
31
  parser (>= 3.0.1.1)
34
32
  ruby-progressbar (1.11.0)
35
- thwait (0.2.0)
36
- e2mmap
37
- unicode-display_width (1.7.0)
38
- yard (0.9.26)
33
+ unicode-display_width (1.8.0)
34
+ webrick (1.7.0)
35
+ yard (0.9.27)
36
+ webrick (~> 1.7.0)
39
37
 
40
38
  PLATFORMS
41
39
  ruby
data/blizzard_api.gemspec CHANGED
@@ -35,7 +35,6 @@ Gem::Specification.new do |spec|
35
35
  spec.require_paths = ['lib']
36
36
 
37
37
  spec.add_runtime_dependency 'redis', '~> 4.1', '>= 4.1.0'
38
- spec.add_runtime_dependency 'thwait', '~> 0.2.0'
39
38
 
40
39
  spec.add_development_dependency 'dotenv'
41
40
  spec.add_development_dependency 'minitest', '~> 5.0'
@@ -0,0 +1,55 @@
1
+ # frozen_string_literal: true
2
+
3
+ module BlizzardApi
4
+ ##
5
+ # Default constants and helper functions for the API format
6
+ module ApiStandards
7
+ # Common endpoints
8
+ BASE_URLS = {
9
+ game_data: 'https://%s.api.blizzard.com/data/%s',
10
+ community: 'https://%s.api.blizzard.com/%s',
11
+ profile: 'https://%s.api.blizzard.com/profile/%s',
12
+ media: 'https://%s.api.blizzard.com/data/%s/media',
13
+ user_profile: 'https://%s.api.blizzard.com/profile/user/%s',
14
+ search: 'https://%s.api.blizzard.com/data/%s/search'
15
+ }.freeze
16
+
17
+ protected
18
+
19
+ def base_url(scope)
20
+ raise ArgumentError, 'Invalid scope' unless BASE_URLS.include? scope
21
+
22
+ format BASE_URLS[scope], region, @game
23
+ end
24
+
25
+ ##
26
+ # Returns a valid version namespace
27
+ #
28
+ # @param [Hash] options A hash containing a valid namespace key
29
+ def endpoint_version(options)
30
+ if options.key? :classic
31
+ 'classic-'
32
+ elsif options.key? :classic1x
33
+ 'classic1x-'
34
+ else
35
+ ''
36
+ end
37
+ end
38
+
39
+ ##
40
+ # Returns a valid namespace string for consuming the api endpoints
41
+ #
42
+ # @param [Hash] options A hash containing the namespace key
43
+ def endpoint_namespace(options)
44
+ version = endpoint_version(options)
45
+
46
+ return "dynamic-#{version}#{region}" if options[:namespace].eql? :dynamic
47
+
48
+ return "static-#{version}#{region}" if options[:namespace].eql? :static
49
+
50
+ return "profile-#{region}" if options[:namespace].eql? :profile
51
+
52
+ raise ArgumentError, 'Invalid namespace scope'
53
+ end
54
+ end
55
+ end
@@ -23,6 +23,12 @@ module BlizzardApi
23
23
  # @return [String] Default region
24
24
  attr_accessor :region
25
25
 
26
+ ##
27
+ # @!attribute mode
28
+ # Api response mode :regular or :extended.
29
+ # @return [Symbol] Default API response mode
30
+ attr_accessor :mode
31
+
26
32
  ##
27
33
  # @!attribute use_cache
28
34
  # If true requests will be cached using a Redis server.
@@ -45,18 +51,17 @@ module BlizzardApi
45
51
  attr_accessor :redis_port
46
52
 
47
53
  ##
48
- #
49
- # @!attribute concurrency
50
- # How many threads to use for WoW game data `complete` payloads. Defaults to 4.
51
- # Should be set to the amount of available cores on the system.
52
- # @return [Integer] Concurrency
53
- attr_writer :concurrency
54
+ # @!attribute redis_database
55
+ # Redis databse.
56
+ # @see https://redis.io/
57
+ # @return [Integer] Redis database
58
+ attr_accessor :redis_database
54
59
 
55
60
  ##
56
- # @!attribute access_token
57
- # Access token. Optional. If you don't provide one it will be generate using your client credentials.
58
- # @return [String] Access token.
59
- attr_accessor :access_token
61
+ # @!attribute cache_access_token
62
+ # If set to true and cache is enabled the current access token will be cached and recovered from Redis
63
+ # @return [Boolean] Access token.
64
+ attr_accessor :cache_access_token
60
65
 
61
66
  ##
62
67
  # This method return the singleton instance of the configuration module. Use this to initialize the default values
@@ -73,18 +78,16 @@ module BlizzardApi
73
78
  # config.use_cache = true
74
79
  # config.redis_host = ENV['REDIS_HOST']
75
80
  # config.redis_port = ENV['REDIS_PORT']
76
- # config.format = :json
77
- #
78
- # config.icons_directory = './wow/icons'
79
- # config.guild_crest_directory = './wow/guild_crest'
80
- # config.wow_character_profile_directory = './wow/profile'
81
81
  # end
82
82
  def configure
83
83
  yield self
84
84
  end
85
85
 
86
- def concurrency
87
- @concurrency ||= 4
86
+ ##
87
+ # Initializes some default values for the main module
88
+ def self.extended(base)
89
+ base.redis_port = 1
90
+ base.mode = :regular
88
91
  end
89
92
  end
90
93
  end
@@ -22,7 +22,7 @@ module BlizzardApi
22
22
  # @see https://develop.battle.net/documentation/guides/using-oauth/authorization-code-flow
23
23
  def index(battletag, oauth_token, **options)
24
24
  opts = { access_token: oauth_token, ttl: CACHE_TRIMESTER }.merge(options)
25
- api_request "#{base_url(:community)}/profile/#{parse_battle_tag(battletag)}/", opts
25
+ api_request "#{base_url(:community)}/profile/#{parse_battle_tag(battletag)}/", **opts
26
26
  end
27
27
 
28
28
  ##
@@ -38,7 +38,7 @@ module BlizzardApi
38
38
  # @see https://develop.battle.net/documentation/guides/using-oauth/authorization-code-flow
39
39
  def hero(battletag, oauth_token, hero_id, **options)
40
40
  opts = { access_token: oauth_token, ttl: CACHE_TRIMESTER }.merge(options)
41
- api_request "#{base_url(:community)}/profile/#{parse_battle_tag(battletag)}/hero/#{hero_id}", opts
41
+ api_request "#{base_url(:community)}/profile/#{parse_battle_tag(battletag)}/hero/#{hero_id}", **opts
42
42
  end
43
43
 
44
44
  ##
@@ -54,7 +54,7 @@ module BlizzardApi
54
54
  # @see https://develop.battle.net/documentation/guides/using-oauth/authorization-code-flow
55
55
  def hero_items(battletag, oauth_token, hero_id, **options)
56
56
  opts = { access_token: oauth_token, ttl: CACHE_TRIMESTER }.merge(options)
57
- api_request "#{base_url(:community)}/profile/#{parse_battle_tag(battletag)}/hero/#{hero_id}/items", opts
57
+ api_request "#{base_url(:community)}/profile/#{parse_battle_tag(battletag)}/hero/#{hero_id}/items", **opts
58
58
  end
59
59
 
60
60
  ##
@@ -70,7 +70,7 @@ module BlizzardApi
70
70
  # @see https://develop.battle.net/documentation/guides/using-oauth/authorization-code-flow
71
71
  def hero_follower_items(battletag, oauth_token, hero_id, **options)
72
72
  opts = { access_token: oauth_token, ttl: CACHE_TRIMESTER }.merge(options)
73
- api_request "#{base_url(:community)}/profile/#{parse_battle_tag(battletag)}/hero/#{hero_id}/follower-items", opts
73
+ api_request "#{base_url(:community)}/profile/#{parse_battle_tag(battletag)}/hero/#{hero_id}/follower-items", **opts
74
74
  end
75
75
 
76
76
  private
@@ -4,8 +4,8 @@ module BlizzardApi
4
4
  module Diablo
5
5
  # Generic endpoint to support most data requests with minor configurations
6
6
  class GenericDataEndpoint < Diablo::Request
7
- def initialize(region = nil, mode = :regular)
8
- super region, mode
7
+ def initialize(**options)
8
+ super(**options)
9
9
  endpoint_setup
10
10
  @ttl ||= CACHE_DAY
11
11
  end
@@ -5,9 +5,9 @@ module BlizzardApi
5
5
  # Diablo III requests
6
6
  class Request < BlizzardApi::Request
7
7
  ##
8
- # @!macro regions
9
- def initialize(region = nil, mode = :regular)
10
- super region, mode
8
+ # @!macro init_options
9
+ def initialize(**options)
10
+ super(**options)
11
11
  @game = 'd3'
12
12
  end
13
13
  end
@@ -1,5 +1,11 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ ##
4
+ # @!macro [new] init_options
5
+ # @param options [Hash] Initialization options
6
+ # @option options [String] :region API region
7
+ # @option options [Symbol] :model API mode (:regular, :extended)
8
+
3
9
  module BlizzardApi
4
10
  # Diablo III related classes
5
11
  module Diablo
@@ -11,17 +17,17 @@ module BlizzardApi
11
17
  require_relative 'diablo/game_data/era'
12
18
 
13
19
  ##
14
- # @param region [String] API Region
20
+ # @!macro init_options
15
21
  # @return {Season}
16
- def self.season(region = BlizzardApi.region)
17
- BlizzardApi::Diablo::Season.new(region)
22
+ def self.season(**options)
23
+ BlizzardApi::Diablo::Season.new(**options)
18
24
  end
19
25
 
20
26
  ##
21
- # @param region [String] API Region
27
+ # @!macro init_options
22
28
  # @return {Era}
23
- def self.era(region = BlizzardApi.region)
24
- BlizzardApi::Diablo::Era.new(region)
29
+ def self.era(**options)
30
+ BlizzardApi::Diablo::Era.new(**options)
25
31
  end
26
32
 
27
33
  # Diablo community api
@@ -34,52 +40,52 @@ module BlizzardApi
34
40
  require_relative 'diablo/community/profile'
35
41
 
36
42
  ##
37
- # @param region [String] API Region
43
+ # @!macro init_options
38
44
  # @return {Act}
39
- def self.act(region = BlizzardApi.region)
40
- BlizzardApi::Diablo::Act.new(region)
45
+ def self.act(**options)
46
+ BlizzardApi::Diablo::Act.new(**options)
41
47
  end
42
48
 
43
49
  ##
44
- # @param region [String] API Region
50
+ # @!macro init_options
45
51
  # @return {Artisan}
46
- def self.artisan(region = BlizzardApi.region)
47
- BlizzardApi::Diablo::Artisan.new(region)
52
+ def self.artisan(**options)
53
+ BlizzardApi::Diablo::Artisan.new(**options)
48
54
  end
49
55
 
50
56
  ##
51
- # @param region [String] API Region
57
+ # @!macro init_options
52
58
  # @return {Follower}
53
- def self.follower(region = BlizzardApi.region)
54
- BlizzardApi::Diablo::Follower.new(region)
59
+ def self.follower(**options)
60
+ BlizzardApi::Diablo::Follower.new(**options)
55
61
  end
56
62
 
57
63
  ##
58
- # @param region [String] API Region
64
+ # @!macro init_options
59
65
  # @return {Character}
60
- def self.character(region = BlizzardApi.region)
61
- BlizzardApi::Diablo::Character.new(region)
66
+ def self.character(**options)
67
+ BlizzardApi::Diablo::Character.new(**options)
62
68
  end
63
69
 
64
70
  ##
65
- # @param region [String] API Region
71
+ # @!macro init_options
66
72
  # @return {ItemType}
67
- def self.item_type(region = BlizzardApi.region)
68
- BlizzardApi::Diablo::ItemType.new(region)
73
+ def self.item_type(**options)
74
+ BlizzardApi::Diablo::ItemType.new(**options)
69
75
  end
70
76
 
71
77
  ##
72
- # @param region [String] API Region
78
+ # @!macro init_options
73
79
  # @return {Type}
74
- def self.item(region = BlizzardApi.region)
75
- BlizzardApi::Diablo::Item.new(region)
80
+ def self.item(**options)
81
+ BlizzardApi::Diablo::Item.new(**options)
76
82
  end
77
83
 
78
84
  ##
79
- # @param region [String] API Region
85
+ # @!macro init_options
80
86
  # @return {Profile}
81
- def self.profile(region = BlizzardApi.region)
82
- BlizzardApi::Diablo::Profile.new(region)
87
+ def self.profile(**options)
88
+ BlizzardApi::Diablo::Profile.new(**options)
83
89
  end
84
90
  end
85
91
  end
@@ -4,8 +4,8 @@ module BlizzardApi
4
4
  module Hearthstone
5
5
  # Generic endpoint to support most data requests with minor configurations
6
6
  class GenericDataEndpoint < Hearthstone::Request
7
- def initialize(region = nil, mode = :regular)
8
- super region, mode
7
+ def initialize(**options)
8
+ super(**options)
9
9
  endpoint_setup
10
10
  @ttl ||= CACHE_DAY
11
11
  end
@@ -5,9 +5,9 @@ module BlizzardApi
5
5
  # Hearthstone requests
6
6
  class Request < BlizzardApi::Request
7
7
  ##
8
- # @!macro regions
9
- def initialize(region = nil, mode = :regular)
10
- super region, mode
8
+ # @!macro init_options
9
+ def initialize(**options)
10
+ super(**options)
11
11
  @game = 'hearthstone'
12
12
  end
13
13
  end
@@ -1,5 +1,11 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ ##
4
+ # @!macro [new] init_options
5
+ # @param options [Hash] Initialization options
6
+ # @option options [String] :region API region
7
+ # @option options [Symbol] :model API mode (:regular, :extended)
8
+
3
9
  module BlizzardApi
4
10
  # Hearthstone related classes
5
11
  module Hearthstone
@@ -13,31 +19,31 @@ module BlizzardApi
13
19
  require_relative 'hearthstone/game_data/metadata'
14
20
 
15
21
  ##
16
- # @param region [String] API Region
22
+ # @!macro init_options
17
23
  # @return {Card}
18
- def self.card(region = BlizzardApi.region)
19
- BlizzardApi::Hearthstone::Card.new(region)
24
+ def self.card(**options)
25
+ BlizzardApi::Hearthstone::Card.new(**options)
20
26
  end
21
27
 
22
28
  ##
23
- # @param region [String] API Region
29
+ # @!macro init_options
24
30
  # @return {Back}
25
- def self.back(region = BlizzardApi.region)
26
- BlizzardApi::Hearthstone::Back.new(region)
31
+ def self.back(**options)
32
+ BlizzardApi::Hearthstone::Back.new(**options)
27
33
  end
28
34
 
29
35
  ##
30
- # @param region [String] API Region
36
+ # @!macro init_options
31
37
  # @return {Deck}
32
- def self.deck(region = BlizzardApi.region)
33
- BlizzardApi::Hearthstone::Deck.new(region)
38
+ def self.deck(**options)
39
+ BlizzardApi::Hearthstone::Deck.new(**options)
34
40
  end
35
41
 
36
42
  ##
37
- # @param region [String] API Region
43
+ # @!macro init_options
38
44
  # @return {Metadata}
39
- def self.metadata(region = BlizzardApi.region)
40
- BlizzardApi::Hearthstone::Metadata.new(region)
45
+ def self.metadata(**options)
46
+ BlizzardApi::Hearthstone::Metadata.new(**options)
41
47
  end
42
48
  end
43
49
  end
@@ -1,5 +1,11 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ ##
4
+ # @!macro [new] init_options
5
+ # @param [Hash] options
6
+ # @option options [String] :region API Region
7
+ # @option options [Symbol] :mode API Mode
8
+
3
9
  ##
4
10
  # @!macro [new] request_options
5
11
  # @param {Hash} options You can specify some options
@@ -9,31 +15,18 @@
9
15
  # @option options [Boolean] :ignore_cache If set to true the request will not use the cache
10
16
  # @option options [Integer] :ttl Override the default time (in seconds) a request should be cached
11
17
  # @option options [DateTime] :since Adds the If-modified-since headers. Will always ignore cache when set.
12
- # @option options [Integer] :concurrency How many threads to use for complete sets of data.
13
- # BEWARE: Might cause 429 responses, in this case lower the number.
14
-
15
- ##
16
- # @!macro [new] regions
17
- # @param {Symbol} region One of the valid API regions *:us*, *:eu*, *:ko*, and *:tw*
18
- # @note This gem do not support nor will support China endpoints
19
18
 
20
19
  ##
21
20
  # @!macro [new] response
22
21
  # @return [Hash] API Response. The actual type of the returned object depends on the *format* option
23
22
  # in the configuration module
24
23
 
25
- ##
26
- # @!macro [new] complete
27
- # Iterates through the {index} response data and fetch additional information using {get}, it results in a more
28
- # complete set of data
29
- # @note IT MAY PERFORM MANY REQUESTS TO FETCH ALL DATA
30
- # @!macro request_options
31
- # @!macro response
32
-
33
24
  module BlizzardApi
34
25
  ##
35
26
  # Simplifies the requests to Blizzard APIS
36
27
  class Request
28
+ include ApiStandards
29
+
37
30
  # One hour cache
38
31
  CACHE_HOUR = 3600
39
32
  # One day cache
@@ -41,16 +34,6 @@ module BlizzardApi
41
34
  # Three (commercial) months cache
42
35
  CACHE_TRIMESTER = CACHE_DAY * 90
43
36
 
44
- # Common endpoints
45
- BASE_URLS = {
46
- game_data: 'https://%s.api.blizzard.com/data/%s',
47
- community: 'https://%s.api.blizzard.com/%s',
48
- profile: 'https://%s.api.blizzard.com/profile/%s',
49
- media: 'https://%s.api.blizzard.com/data/%s/media',
50
- user_profile: 'https://%s.api.blizzard.com/profile/user/%s',
51
- search: 'https://%s.api.blizzard.com/data/%s/search'
52
- }.freeze
53
-
54
37
  ##
55
38
  # @!attribute region
56
39
  # @return [String] Api region
@@ -62,14 +45,14 @@ module BlizzardApi
62
45
  attr_accessor :mode
63
46
 
64
47
  ##
65
- # @!macro regions
66
- def initialize(region = nil, mode = :regular)
67
- self.region = region || BlizzardApi.region
68
- @redis = Redis.new(host: BlizzardApi.redis_host, port: BlizzardApi.redis_port) if BlizzardApi.use_cache
48
+ # @!macro init_options
49
+ def initialize(**options)
50
+ self.region = options[:region] || BlizzardApi.region
69
51
  # Use the shared access_token, or create one if it doesn't exists. This avoids unnecessary calls to create tokens.
70
- @access_token = BlizzardApi.access_token || create_access_token
52
+ create_access_token if BlizzardApi.access_token_expired?
53
+
71
54
  # Mode
72
- @mode = mode
55
+ @mode = options[:mode] || BlizzardApi.mode
73
56
  end
74
57
 
75
58
  require 'net/http'
@@ -79,45 +62,9 @@ module BlizzardApi
79
62
 
80
63
  protected
81
64
 
82
- def base_url(scope)
83
- raise ArgumentError, 'Invalid scope' unless BASE_URLS.include? scope
84
-
85
- format BASE_URLS[scope], region, @game
86
- end
87
-
88
- ##
89
- # Returns a valid version namespace
90
- #
91
- # @param [Hash] options A hash containing a valid namespace key
92
- def endpoint_version(options)
93
- if options.key? :classic
94
- 'classic-'
95
- elsif options.key? :classic1x
96
- 'classic1x-'
97
- else
98
- ''
99
- end
100
- end
101
-
102
- ##
103
- # Returns a valid namespace string for consuming the api endpoints
104
- #
105
- # @param [Hash] options A hash containing the namespace key
106
- def endpoint_namespace(options)
107
- version = endpoint_version(options)
108
- case options[:namespace]
109
- when :dynamic
110
- "dynamic-#{version}#{region}"
111
- when :static
112
- "static-#{version}#{region}"
113
- when :profile
114
- "profile-#{region}"
115
- else
116
- raise ArgumentError, 'Invalid namespace scope'
117
- end
118
- end
119
-
120
65
  def create_access_token
66
+ return if BlizzardApi.restore_access_token
67
+
121
68
  uri = URI.parse("https://#{BlizzardApi.region}.battle.net/oauth/token")
122
69
 
123
70
  http = Net::HTTP.new(uri.host, uri.port)
@@ -129,7 +76,7 @@ module BlizzardApi
129
76
  request.set_form_data grant_type: 'client_credentials'
130
77
 
131
78
  response = http.request(request)
132
- BlizzardApi.access_token = JSON.parse(response.body)['access_token']
79
+ BlizzardApi.save_access_token(JSON.parse(response.body))
133
80
  end
134
81
 
135
82
  def request(url, **options)
@@ -180,16 +127,20 @@ module BlizzardApi
180
127
  !options.fetch(:ignore_cache, false)
181
128
  end
182
129
 
130
+ def http_connection(url)
131
+ Net::HTTP.new(url.host, url.port).tap do |http|
132
+ http.use_ssl = true
133
+ end
134
+ end
135
+
183
136
  def consume_api(url, **options)
184
137
  # Creates a HTTP connection and request to ensure thread safety
185
- http = Net::HTTP.new(url.host, url.port)
186
- http.use_ssl = true
187
138
  request = Net::HTTP::Get.new(url)
188
139
 
189
140
  add_headers request, options
190
141
 
191
142
  # Executes the request
192
- http.request(request).tap do |response|
143
+ http_connection(url).request(request).tap do |response|
193
144
  if mode.eql?(:regular) && ![200, 304].include?(response.code.to_i)
194
145
  raise BlizzardApi::ApiException.new "Request failed with code '#{response.code}' details: #{response.to_hash}", response.code.to_i
195
146
  end
@@ -198,20 +149,20 @@ module BlizzardApi
198
149
 
199
150
  def add_headers(request, options)
200
151
  # Blizzard API documentation states the preferred way to send the access_token is using Bearer token on header
201
- request['Authorization'] = "Bearer #{options.fetch(:access_token, @access_token)}"
152
+ request['Authorization'] = "Bearer #{options.fetch(:access_token, BlizzardApi.access_token)}"
202
153
  # Format If-modified-since option
203
154
  request['If-Modified-Since'] = options[:since].httpdate if options.key? :since
204
155
  options[:headers]&.each { |header, content| request[header] = content }
205
156
  end
206
157
 
207
158
  def save_in_cache(resource_url, data, ttl)
208
- @redis.setex resource_url, ttl, data if BlizzardApi.use_cache
159
+ BlizzardApi.redis_connection.setex resource_url, ttl, data if BlizzardApi.use_cache
209
160
  end
210
161
 
211
162
  def find_in_cache(resource_url)
212
163
  return false unless BlizzardApi.use_cache
213
164
 
214
- @redis.get resource_url if @redis.exists? resource_url
165
+ BlizzardApi.redis_connection.get resource_url if BlizzardApi.redis_connection.exists? resource_url
215
166
  end
216
167
  end
217
168
  end
@@ -16,7 +16,7 @@ module BlizzardApi
16
16
  # @param [Integer] account_id Account ID
17
17
  # @!macro request_options
18
18
  def player(account_id, **options)
19
- api_request "#{base_url(:community)}/player/#{account_id}", { ttl: CACHE_DAY }.merge(options)
19
+ api_request "#{base_url(:community)}/player/#{account_id}", **{ ttl: CACHE_DAY }.merge(options)
20
20
  end
21
21
  end
22
22
  end