blizzard_api 0.6.4 → 1.0.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 +4 -4
- data/CHANGELOG.md +12 -0
- data/Gemfile.lock +11 -13
- data/blizzard_api.gemspec +0 -1
- data/lib/blizzard_api/api_standards.rb +55 -0
- data/lib/blizzard_api/configuration.rb +20 -17
- data/lib/blizzard_api/diablo/game_data/generic_data_endpoint.rb +2 -2
- data/lib/blizzard_api/diablo/request.rb +3 -3
- data/lib/blizzard_api/diablo.rb +33 -27
- data/lib/blizzard_api/hearthstone/game_data/generic_data_endpoint.rb +2 -2
- data/lib/blizzard_api/hearthstone/request.rb +3 -3
- data/lib/blizzard_api/hearthstone.rb +18 -12
- data/lib/blizzard_api/request.rb +27 -76
- data/lib/blizzard_api/starcraft/request.rb +3 -3
- data/lib/blizzard_api/starcraft.rb +20 -14
- data/lib/blizzard_api/token_manager.rb +49 -0
- data/lib/blizzard_api/version.rb +1 -1
- data/lib/blizzard_api/wow/game_data/achievement.rb +1 -16
- data/lib/blizzard_api/wow/game_data/azerite_essence.rb +2 -9
- data/lib/blizzard_api/wow/game_data/connected_realm.rb +1 -8
- data/lib/blizzard_api/wow/game_data/covenant.rb +2 -9
- data/lib/blizzard_api/wow/game_data/creature.rb +2 -13
- data/lib/blizzard_api/wow/game_data/generic_data_endpoint.rb +10 -37
- data/lib/blizzard_api/wow/game_data/guild_crest.rb +4 -10
- data/lib/blizzard_api/wow/game_data/item.rb +3 -18
- data/lib/blizzard_api/wow/game_data/journal.rb +2 -17
- data/lib/blizzard_api/wow/game_data/media.rb +2 -13
- data/lib/blizzard_api/wow/game_data/modified_crafting.rb +1 -12
- data/lib/blizzard_api/wow/game_data/mount.rb +1 -8
- data/lib/blizzard_api/wow/game_data/mythic_keystone.rb +2 -13
- data/lib/blizzard_api/wow/game_data/mythic_keystone_affix.rb +2 -9
- data/lib/blizzard_api/wow/game_data/pet.rb +2 -9
- data/lib/blizzard_api/wow/game_data/playable_class.rb +2 -23
- data/lib/blizzard_api/wow/game_data/playable_race.rb +1 -8
- data/lib/blizzard_api/wow/game_data/playable_specialization.rb +1 -18
- data/lib/blizzard_api/wow/game_data/power_type.rb +1 -8
- data/lib/blizzard_api/wow/game_data/profession.rb +2 -9
- data/lib/blizzard_api/wow/game_data/pvp_region.rb +82 -0
- data/lib/blizzard_api/wow/game_data/pvp_season.rb +7 -9
- data/lib/blizzard_api/wow/game_data/pvp_tier.rb +3 -10
- data/lib/blizzard_api/wow/game_data/quest.rb +2 -9
- data/lib/blizzard_api/wow/game_data/realm.rb +1 -8
- data/lib/blizzard_api/wow/game_data/region.rb +1 -8
- data/lib/blizzard_api/wow/game_data/reputation.rb +2 -9
- data/lib/blizzard_api/wow/game_data/spell.rb +2 -17
- data/lib/blizzard_api/wow/game_data/talent.rb +2 -9
- data/lib/blizzard_api/wow/game_data/tech_talent.rb +2 -9
- data/lib/blizzard_api/wow/game_data/title.rb +1 -16
- data/lib/blizzard_api/wow/profile/profile.rb +2 -2
- data/lib/blizzard_api/wow/request.rb +3 -3
- data/lib/blizzard_api/wow.rb +122 -108
- data/lib/blizzard_api.rb +9 -0
- metadata +5 -16
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 862b08dc9410cd376ae326bd9617b5dc0a83bcdba3bd72096f9f538993bf65ae
|
4
|
+
data.tar.gz: 81822af210c99fe12144be084cbaaa41dc2ad45a3c968d52dda94137e69e3bbc
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 1ad2ee3a2e8c6fdecd512967e86645604ff0b5452fecdf7e7511a9d8fcb9b094aef2e96fcbe34d405221a9f41646635a61a0d07281f0a4da3b6b0cb45e59832a
|
7
|
+
data.tar.gz: 3cfa00ba28278318d9348d1ce81fa63f83fb7b455f5a0340360ed402d95c36b7a2a28b9c8a16c4ca3252e55e6dc6e6d721f53e918b923e1726430708f0ec1dc8
|
data/CHANGELOG.md
CHANGED
@@ -1,5 +1,17 @@
|
|
1
1
|
Please view this file on the master branch, otherwise it may be outdated
|
2
2
|
|
3
|
+
**Version 1.0.0**
|
4
|
+
|
5
|
+
Removed the `complete` method from WoW game data endpoints.
|
6
|
+
Removed the `concurrency` request and configuration option as it is not necessary anymore.
|
7
|
+
Removed the `thwait` dependency.
|
8
|
+
|
9
|
+
Added the `redis_database` option to support selecting the redis database for caching data.
|
10
|
+
The gem will now share a single Redis connection across all calls.
|
11
|
+
The gem now creates a new token on demand if the previous one has expired.
|
12
|
+
It is now possible to cache the token in Redis to avoid needlessly creating a new token.
|
13
|
+
It is now possible to set the default mode for API calls
|
14
|
+
|
3
15
|
**Version 0.6.4**
|
4
16
|
|
5
17
|
Fixed argument propagation in SC2 legacy profile methods.
|
data/Gemfile.lock
CHANGED
@@ -1,24 +1,22 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
blizzard_api (0.
|
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
|
-
|
14
|
-
|
15
|
-
|
16
|
-
parser (3.0.2.0)
|
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
17
|
rake (13.0.6)
|
20
|
-
redis (4.
|
21
|
-
regexp_parser (2.
|
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.
|
30
|
+
rubocop-ast (1.15.1)
|
33
31
|
parser (>= 3.0.1.1)
|
34
32
|
ruby-progressbar (1.11.0)
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
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
|
-
#
|
50
|
-
#
|
51
|
-
#
|
52
|
-
|
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
|
57
|
-
#
|
58
|
-
# @return [
|
59
|
-
attr_accessor :
|
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
|
-
|
87
|
-
|
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
|
@@ -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(
|
8
|
-
super
|
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
|
9
|
-
def initialize(
|
10
|
-
super
|
8
|
+
# @!macro init_options
|
9
|
+
def initialize(**options)
|
10
|
+
super(**options)
|
11
11
|
@game = 'd3'
|
12
12
|
end
|
13
13
|
end
|
data/lib/blizzard_api/diablo.rb
CHANGED
@@ -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
|
-
#
|
20
|
+
# @!macro init_options
|
15
21
|
# @return {Season}
|
16
|
-
def self.season(
|
17
|
-
BlizzardApi::Diablo::Season.new(
|
22
|
+
def self.season(**options)
|
23
|
+
BlizzardApi::Diablo::Season.new(**options)
|
18
24
|
end
|
19
25
|
|
20
26
|
##
|
21
|
-
#
|
27
|
+
# @!macro init_options
|
22
28
|
# @return {Era}
|
23
|
-
def self.era(
|
24
|
-
BlizzardApi::Diablo::Era.new(
|
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
|
-
#
|
43
|
+
# @!macro init_options
|
38
44
|
# @return {Act}
|
39
|
-
def self.act(
|
40
|
-
BlizzardApi::Diablo::Act.new(
|
45
|
+
def self.act(**options)
|
46
|
+
BlizzardApi::Diablo::Act.new(**options)
|
41
47
|
end
|
42
48
|
|
43
49
|
##
|
44
|
-
#
|
50
|
+
# @!macro init_options
|
45
51
|
# @return {Artisan}
|
46
|
-
def self.artisan(
|
47
|
-
BlizzardApi::Diablo::Artisan.new(
|
52
|
+
def self.artisan(**options)
|
53
|
+
BlizzardApi::Diablo::Artisan.new(**options)
|
48
54
|
end
|
49
55
|
|
50
56
|
##
|
51
|
-
#
|
57
|
+
# @!macro init_options
|
52
58
|
# @return {Follower}
|
53
|
-
def self.follower(
|
54
|
-
BlizzardApi::Diablo::Follower.new(
|
59
|
+
def self.follower(**options)
|
60
|
+
BlizzardApi::Diablo::Follower.new(**options)
|
55
61
|
end
|
56
62
|
|
57
63
|
##
|
58
|
-
#
|
64
|
+
# @!macro init_options
|
59
65
|
# @return {Character}
|
60
|
-
def self.character(
|
61
|
-
BlizzardApi::Diablo::Character.new(
|
66
|
+
def self.character(**options)
|
67
|
+
BlizzardApi::Diablo::Character.new(**options)
|
62
68
|
end
|
63
69
|
|
64
70
|
##
|
65
|
-
#
|
71
|
+
# @!macro init_options
|
66
72
|
# @return {ItemType}
|
67
|
-
def self.item_type(
|
68
|
-
BlizzardApi::Diablo::ItemType.new(
|
73
|
+
def self.item_type(**options)
|
74
|
+
BlizzardApi::Diablo::ItemType.new(**options)
|
69
75
|
end
|
70
76
|
|
71
77
|
##
|
72
|
-
#
|
78
|
+
# @!macro init_options
|
73
79
|
# @return {Type}
|
74
|
-
def self.item(
|
75
|
-
BlizzardApi::Diablo::Item.new(
|
80
|
+
def self.item(**options)
|
81
|
+
BlizzardApi::Diablo::Item.new(**options)
|
76
82
|
end
|
77
83
|
|
78
84
|
##
|
79
|
-
#
|
85
|
+
# @!macro init_options
|
80
86
|
# @return {Profile}
|
81
|
-
def self.profile(
|
82
|
-
BlizzardApi::Diablo::Profile.new(
|
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(
|
8
|
-
super
|
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
|
9
|
-
def initialize(
|
10
|
-
super
|
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
|
-
#
|
22
|
+
# @!macro init_options
|
17
23
|
# @return {Card}
|
18
|
-
def self.card(
|
19
|
-
BlizzardApi::Hearthstone::Card.new(
|
24
|
+
def self.card(**options)
|
25
|
+
BlizzardApi::Hearthstone::Card.new(**options)
|
20
26
|
end
|
21
27
|
|
22
28
|
##
|
23
|
-
#
|
29
|
+
# @!macro init_options
|
24
30
|
# @return {Back}
|
25
|
-
def self.back(
|
26
|
-
BlizzardApi::Hearthstone::Back.new(
|
31
|
+
def self.back(**options)
|
32
|
+
BlizzardApi::Hearthstone::Back.new(**options)
|
27
33
|
end
|
28
34
|
|
29
35
|
##
|
30
|
-
#
|
36
|
+
# @!macro init_options
|
31
37
|
# @return {Deck}
|
32
|
-
def self.deck(
|
33
|
-
BlizzardApi::Hearthstone::Deck.new(
|
38
|
+
def self.deck(**options)
|
39
|
+
BlizzardApi::Hearthstone::Deck.new(**options)
|
34
40
|
end
|
35
41
|
|
36
42
|
##
|
37
|
-
#
|
43
|
+
# @!macro init_options
|
38
44
|
# @return {Metadata}
|
39
|
-
def self.metadata(
|
40
|
-
BlizzardApi::Hearthstone::Metadata.new(
|
45
|
+
def self.metadata(**options)
|
46
|
+
BlizzardApi::Hearthstone::Metadata.new(**options)
|
41
47
|
end
|
42
48
|
end
|
43
49
|
end
|
data/lib/blizzard_api/request.rb
CHANGED
@@ -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
|
66
|
-
def initialize(
|
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
|
-
|
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.
|
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
|
-
|
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,
|
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
|
-
|
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
|
-
|
165
|
+
BlizzardApi.redis_connection.get resource_url if BlizzardApi.redis_connection.exists? resource_url
|
215
166
|
end
|
216
167
|
end
|
217
168
|
end
|
@@ -14,9 +14,9 @@ module BlizzardApi
|
|
14
14
|
SC_REGION = { US: 1, EU: 2, KO: 3, TW: 3 }.freeze
|
15
15
|
|
16
16
|
##
|
17
|
-
# @!macro
|
18
|
-
def initialize(
|
19
|
-
super
|
17
|
+
# @!macro init_options
|
18
|
+
def initialize(**options)
|
19
|
+
super(**options)
|
20
20
|
@game = 'sc2'
|
21
21
|
end
|
22
22
|
|