blizzard_api 0.3.11 → 0.5.2

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.
Files changed (37) hide show
  1. checksums.yaml +4 -4
  2. data/.rubocop.yml +2 -1
  3. data/CHANGELOG.md +65 -0
  4. data/Gemfile.lock +23 -14
  5. data/README.md +45 -0
  6. data/blizzard_api.gemspec +2 -0
  7. data/lib/blizzard_api/diablo/community/item.rb +1 -1
  8. data/lib/blizzard_api/diablo/game_data/generic_data_endpoint.rb +2 -2
  9. data/lib/blizzard_api/diablo/request.rb +2 -2
  10. data/lib/blizzard_api/hearthstone/game_data/generic_data_endpoint.rb +2 -2
  11. data/lib/blizzard_api/hearthstone/request.rb +2 -2
  12. data/lib/blizzard_api/request.rb +46 -38
  13. data/lib/blizzard_api/starcraft/request.rb +2 -2
  14. data/lib/blizzard_api/version.rb +1 -1
  15. data/lib/blizzard_api/wow.rb +35 -0
  16. data/lib/blizzard_api/wow/game_data/azerite_essence.rb +2 -0
  17. data/lib/blizzard_api/wow/game_data/connected_realm.rb +2 -0
  18. data/lib/blizzard_api/wow/game_data/covenant.rb +79 -0
  19. data/lib/blizzard_api/wow/game_data/creature.rb +2 -0
  20. data/lib/blizzard_api/wow/game_data/generic_data_endpoint.rb +4 -4
  21. data/lib/blizzard_api/wow/game_data/item.rb +2 -0
  22. data/lib/blizzard_api/wow/game_data/journal.rb +15 -0
  23. data/lib/blizzard_api/wow/game_data/media.rb +37 -0
  24. data/lib/blizzard_api/wow/game_data/modified_crafting.rb +67 -0
  25. data/lib/blizzard_api/wow/game_data/mount.rb +2 -0
  26. data/lib/blizzard_api/wow/game_data/pet.rb +46 -0
  27. data/lib/blizzard_api/wow/game_data/realm.rb +2 -0
  28. data/lib/blizzard_api/wow/game_data/spell.rb +2 -0
  29. data/lib/blizzard_api/wow/game_data/tech_talent.rb +57 -0
  30. data/lib/blizzard_api/wow/profile/character_profile.rb +19 -1
  31. data/lib/blizzard_api/wow/profile/guild.rb +2 -0
  32. data/lib/blizzard_api/wow/profile/profile.rb +2 -2
  33. data/lib/blizzard_api/wow/request.rb +2 -2
  34. data/lib/blizzard_api/wow/search/search_composer.rb +97 -0
  35. data/lib/blizzard_api/wow/search/search_request.rb +24 -0
  36. data/lib/blizzard_api/wow/slug.rb +12 -0
  37. metadata +43 -8
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 0d749ca8885288890aa3fd989b55d761520775a0187bc395802152d09a27b57d
4
- data.tar.gz: b9da4c8d1aa1c505737a258780e80db4c41a0ea789fef38b7d673cdd5ad3a29b
3
+ metadata.gz: 3bf4766a30de47652d2693fb7480ef30e5ef6559fbc6f3bb7cad50a35ab4b1a6
4
+ data.tar.gz: 447d04397f442f5b7ad4fab941bf54fba397f7b855a26bfd62e67cefad30f78f
5
5
  SHA512:
6
- metadata.gz: 2320bad31262928a97d77ddf5092ad86a80278ac88572be33a9f252aa639d99973a8c3554b786f3c95fc9a05be0aba099412038eaee56bda11a9e6414221ff40
7
- data.tar.gz: 7a9df7fb947da25b9e5ae4e19c6384acfe3f5111f6d4ca2615f4ab87ee80cdfde25bb7cbebde597e2c5bebe4b303a661605e6ff51ef68860c24c07895883c844
6
+ metadata.gz: 851bdad8472fcaf5e385b8caba51376636ea30be09ee79ecb5a383971196945574b8a3073b465f940a3aee123f885ab5358d3f2ba6bcf5eb38fb59da5bcdb660
7
+ data.tar.gz: 48bfe00c18fea3f3d296f1b49e800e54c67ff1a6b8e5972086e4d2f95cc014b5751e53c10a526a4e2bf103342cdea6c441a2987e59e00b5c0cfdc2d3d16d4334
@@ -1,6 +1,6 @@
1
1
  inherit_from: .rubocop_todo.yml
2
2
 
3
- Metrics/LineLength:
3
+ Layout/LineLength:
4
4
  Max: 140
5
5
 
6
6
  Metrics/ModuleLength:
@@ -12,6 +12,7 @@ Metrics/AbcSize:
12
12
 
13
13
  AllCops:
14
14
  TargetRubyVersion: 2.5
15
+ NewCops: enable
15
16
  Exclude:
16
17
  - 'vendor/**/*'
17
18
  - 'bin/**/*'
@@ -1,5 +1,70 @@
1
1
  Please view this file on the master branch, otherwise it may be outdated
2
2
 
3
+ **Version 0.5.2**
4
+
5
+ Added new endpoints: https://us.forums.blizzard.com/en/blizzard/t/wow-shadowlands-api-update-covenenats-soulbinds-more/13385
6
+
7
+ **Version 0.5.1**
8
+
9
+ Added new endpoints: https://us.forums.blizzard.com/en/blizzard/t/wow-game-data-api-modified-crafting-support/12727
10
+
11
+ **Version 0.5.0**
12
+
13
+ This version brings a lot of internal changes to the way the gem works. While
14
+ there no breaking change is expected use it carefully.
15
+
16
+ ## New features:
17
+
18
+ ### Extended mode
19
+
20
+ When creating a request you can now specify **mode** as the last argument. Available modes:
21
+ * **regular**: No changes, should work as it always did.
22
+ * **extended**: All requests now return an array with two objects, the actual HTTPResponse object and the usual Hash.
23
+
24
+ ```ruby
25
+ api_client = BlizzardApi::Wow::Item.new 'us', :extended
26
+ response, item_data = api_client.get 35_000
27
+
28
+ puts response.code # 200
29
+ puts item_data[:name][:en_US] # Brutal Gladiator's Dragonhide Legguards
30
+ ```
31
+
32
+ This is intended to expose the response code and headers.
33
+
34
+ **Important**: Extended mode completely disables the cache.
35
+
36
+ ### Custom headers
37
+
38
+ You an now pass custom headers in the **options** hash.
39
+
40
+ There is also a new shorthand for the `If-Modified-Since` header.
41
+
42
+ ```ruby
43
+ # If-Modified-Since shorhand
44
+ auction_data = BlizzardApi::Wow.auction.get 1146, since: DateTime.parse('2099-01-01Z')
45
+
46
+ # Using custom headers
47
+ auction_data = BlizzardApi::Wow.auction.get 1146, headers: { 'If-Modified-Since' => 'Sun, 27 Sep 2020 02:17:03 GMT' }
48
+ ```
49
+
50
+ **Important**
51
+ * Headers are not part of the cache key, use the option `ignore_cache: true` when needed.
52
+ * The `since` shorthand will always disable the cache.
53
+
54
+ **Version 0.4.2**
55
+
56
+ Added new retail and classic search endpoints described here: https://us.forums.blizzard.com/en/blizzard/t/world-of-warcraft-api-patch-notes-20200708/10310
57
+
58
+ **Version 0.4.1**
59
+
60
+ Added new retail and classic endpoints described here: https://us.forums.blizzard.com/en/blizzard/t/world-of-warcraft-api-patch-notes-20200609/8902
61
+
62
+ **Version 0.4.0**
63
+
64
+ Added support to searchable endpoints
65
+
66
+ https://develop.battle.net/documentation/world-of-warcraft/guides/search
67
+
3
68
  **Version 0.3.11**
4
69
 
5
70
  Fixed D3 item URL.
@@ -1,39 +1,48 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- blizzard_api (0.3.11)
4
+ blizzard_api (0.5.1)
5
5
  redis (~> 4.1, >= 4.1.0)
6
6
 
7
7
  GEM
8
8
  remote: https://rubygems.org/
9
9
  specs:
10
- ast (2.4.0)
11
- jaro_winkler (1.5.3)
12
- minitest (5.11.3)
13
- parallel (1.17.0)
14
- parser (2.6.3.0)
15
- ast (~> 2.4.0)
10
+ ast (2.4.1)
11
+ dotenv (2.7.6)
12
+ minitest (5.14.2)
13
+ parallel (1.19.2)
14
+ parser (2.7.1.5)
15
+ ast (~> 2.4.1)
16
16
  rainbow (3.0.0)
17
17
  rake (13.0.1)
18
- redis (4.1.3)
19
- rubocop (0.74.0)
20
- jaro_winkler (~> 1.5.1)
18
+ redis (4.2.2)
19
+ regexp_parser (1.8.0)
20
+ rexml (3.2.4)
21
+ rubocop (0.92.0)
21
22
  parallel (~> 1.10)
22
- parser (>= 2.6)
23
+ parser (>= 2.7.1.5)
23
24
  rainbow (>= 2.2.2, < 4.0)
25
+ regexp_parser (>= 1.7)
26
+ rexml
27
+ rubocop-ast (>= 0.5.0)
24
28
  ruby-progressbar (~> 1.7)
25
- unicode-display_width (>= 1.4.0, < 1.7)
29
+ unicode-display_width (>= 1.4.0, < 2.0)
30
+ rubocop-ast (0.6.0)
31
+ parser (>= 2.7.1.5)
26
32
  ruby-progressbar (1.10.1)
27
- unicode-display_width (1.6.0)
33
+ unicode-display_width (1.7.0)
34
+ yard (0.9.25)
28
35
 
29
36
  PLATFORMS
30
37
  ruby
31
38
 
32
39
  DEPENDENCIES
33
40
  blizzard_api!
41
+ dotenv
34
42
  minitest (~> 5.0)
35
43
  rake (~> 13.0)
36
44
  rubocop (~> 0.61)
45
+ yard
37
46
 
38
47
  BUNDLED WITH
39
- 2.1.2
48
+ 2.1.4
data/README.md CHANGED
@@ -73,6 +73,46 @@ Most **data** endpoints will have always 3 methods available `index`, `get` and
73
73
  * `get` is used to get all information about a entry of the index returned data. It receives an id or slug as the first parameter, that depends on the endpoint.
74
74
  * `complete` is a complete information of all items listed in index. **This may perform various calls to the blizzard api** only use if you really need all information.
75
75
 
76
+ ### 3.1 Searchable endpoints
77
+
78
+ Some endpoints support search filters. To perform a search you can use the following formats:
79
+
80
+
81
+ To use the **or** operator you may pass an array of values as argument to `where` or `where_not` methods.
82
+ ```ruby
83
+ realm = BlizzardApi::Wow.realm
84
+ realm_data = realm.search(1, 100) do |options|
85
+ options.where 'name.en_US', %w[Azralon Nemesis]
86
+ end
87
+ ```
88
+
89
+ To use the **and** operator you may call `where` or `where_not` multiple times methods.
90
+ ```ruby
91
+ realm = BlizzardApi::Wow.realm
92
+ realm_data = realm.search(1, 100) do |options|
93
+ options.where 'name.en_US', 'Azralon'
94
+ options.where 'id', 3209
95
+ end
96
+ ```
97
+
98
+ To use the **range** operator you may pass a hash to `where` or `where_not`.
99
+ ```ruby
100
+ realm = BlizzardApi::Wow.realm
101
+ realm_data = realm.search(1, 100) do |options|
102
+ options.where 'id', min: 3209, max: 4000, mode: :exclusive
103
+ end
104
+ ```
105
+ *Note*: If you don't pass the `mode` key as `:exclusive` it will be `:inclusive` by default.
106
+
107
+ To **sort** fields you may call the `order_by` method multiple times:
108
+ ```ruby
109
+ realm = BlizzardApi::Wow.realm
110
+ realm_data = realm.search(1, 100) do |options|
111
+ options.where 'id', min: 3209, max: 4000, mode: :exclusive
112
+ options.order_by 'id', :desc
113
+ end
114
+ ```
115
+
76
116
  ## 4. Available endpoints
77
117
 
78
118
  **Hint**: All methods support an additional optional hash parameter that allows you to override the following configurations for a single call:
@@ -105,6 +145,7 @@ Most **data** endpoints will have always 3 methods available `index`, `get` and
105
145
  - types
106
146
  - type :id
107
147
  - display_media :id
148
+ - search
108
149
  * Blizzard::Wow::Guild
109
150
  - rewards
110
151
  - perks
@@ -171,6 +212,7 @@ Most **data** endpoints will have always 3 methods available `index`, `get` and
171
212
  - get :id
172
213
  - complete
173
214
  - status :realms
215
+ - search
174
216
  * Blizzard::Wow::Region
175
217
  - index
176
218
  - get :id
@@ -191,10 +233,12 @@ Most **data** endpoints will have always 3 methods available `index`, `get` and
191
233
  - class :id
192
234
  - subclass :class_id, :subclass_id
193
235
  - media :id
236
+ - search
194
237
  * Blizzard::Wow::AzeriteEssence
195
238
  - index
196
239
  - get :id
197
240
  - media :id
241
+ - search
198
242
  * Blizzard::Wow::ReputationTier
199
243
  - index
200
244
  - get :id
@@ -222,6 +266,7 @@ Most **data** endpoints will have always 3 methods available `index`, `get` and
222
266
  - get :id
223
267
  * Blizzard::Wow::Spell
224
268
  - get :id
269
+ - search
225
270
  * Blizzard::Wow::Zone
226
271
  - index
227
272
  - get :id
@@ -34,7 +34,9 @@ Gem::Specification.new do |spec|
34
34
 
35
35
  spec.add_runtime_dependency 'redis', '~> 4.1', '>= 4.1.0'
36
36
 
37
+ spec.add_development_dependency 'dotenv'
37
38
  spec.add_development_dependency 'minitest', '~> 5.0'
38
39
  spec.add_development_dependency 'rake', '~> 13.0'
39
40
  spec.add_development_dependency 'rubocop', '~> 0.61'
41
+ spec.add_development_dependency 'yard'
40
42
  end
@@ -13,7 +13,7 @@ module BlizzardApi
13
13
  ##
14
14
  # Return information about an item
15
15
  #
16
- # @param item_slug [String] Item slug
16
+ # @param item_slug_and_id [String] Item slug
17
17
  # @!macro request_options
18
18
  #
19
19
  # @!macro response
@@ -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)
8
- super region
7
+ def initialize(region = nil, mode = :regular)
8
+ super region, mode
9
9
  endpoint_setup
10
10
  @ttl ||= CACHE_DAY
11
11
  end
@@ -6,8 +6,8 @@ module BlizzardApi
6
6
  class Request < BlizzardApi::Request
7
7
  ##
8
8
  # @!macro regions
9
- def initialize(region = nil)
10
- super region
9
+ def initialize(region = nil, mode = :regular)
10
+ super region, mode
11
11
  @game = 'd3'
12
12
  end
13
13
  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)
8
- super region
7
+ def initialize(region = nil, mode = :regular)
8
+ super region, mode
9
9
  endpoint_setup
10
10
  @ttl ||= CACHE_DAY
11
11
  end
@@ -6,8 +6,8 @@ module BlizzardApi
6
6
  class Request < BlizzardApi::Request
7
7
  ##
8
8
  # @!macro regions
9
- def initialize(region = nil)
10
- super region
9
+ def initialize(region = nil, mode = :regular)
10
+ super region, mode
11
11
  @game = 'hearthstone'
12
12
  end
13
13
  end
@@ -8,6 +8,7 @@
8
8
  # @option options [String] :access_token Overrides the access_token for a single call
9
9
  # @option options [Boolean] :ignore_cache If set to true the request will not use the cache
10
10
  # @option options [Integer] :ttl Override the default time (in seconds) a request should be cached
11
+ # @option options [DateTime] :since Adds the If-modified-since headers. Will always ignore cache when set.
11
12
 
12
13
  ##
13
14
  # @!macro [new] regions
@@ -31,18 +32,12 @@ module BlizzardApi
31
32
  ##
32
33
  # Simplifies the requests to Blizzard APIS
33
34
  class Request
34
- # One minute cache
35
- CACHE_MINUTE = 60
36
35
  # One hour cache
37
- CACHE_HOUR = 60 * CACHE_MINUTE
36
+ CACHE_HOUR = 3600
38
37
  # One day cache
39
38
  CACHE_DAY = 24 * CACHE_HOUR
40
- # One week cache
41
- CACHE_WEEK = CACHE_DAY * 7
42
- # One (commercial) month cache
43
- CACHE_MONTH = CACHE_DAY * 30
44
39
  # Three (commercial) months cache
45
- CACHE_TRIMESTER = CACHE_MONTH * 3
40
+ CACHE_TRIMESTER = CACHE_DAY * 90
46
41
 
47
42
  # Common endpoints
48
43
  BASE_URLS = {
@@ -50,7 +45,8 @@ module BlizzardApi
50
45
  community: 'https://%s.api.blizzard.com/%s',
51
46
  profile: 'https://%s.api.blizzard.com/profile/%s',
52
47
  media: 'https://%s.api.blizzard.com/data/%s/media',
53
- user_profile: 'https://%s.api.blizzard.com/profile/user/%s'
48
+ user_profile: 'https://%s.api.blizzard.com/profile/user/%s',
49
+ search: 'https://%s.api.blizzard.com/data/%s/search'
54
50
  }.freeze
55
51
 
56
52
  ##
@@ -58,13 +54,20 @@ module BlizzardApi
58
54
  # @return [String] Api region
59
55
  attr_accessor :region
60
56
 
57
+ ##
58
+ # @!attribute mode
59
+ # @return [:regular, :extended]
60
+ attr_accessor :mode
61
+
61
62
  ##
62
63
  # @!macro regions
63
- def initialize(region = nil)
64
+ def initialize(region = nil, mode = :regular)
64
65
  self.region = region || BlizzardApi.region
65
66
  @redis = Redis.new(host: BlizzardApi.redis_host, port: BlizzardApi.redis_port) if BlizzardApi.use_cache
66
67
  # Use the shared access_token, or create one if it doesn't exists. This avoids unnecessary calls to create tokens.
67
68
  @access_token = BlizzardApi.access_token || create_access_token
69
+ # Mode
70
+ @mode = mode
68
71
  end
69
72
 
70
73
  require 'net/http'
@@ -87,7 +90,7 @@ module BlizzardApi
87
90
  def endpoint_namespace(options)
88
91
  case options[:namespace]
89
92
  when :dynamic
90
- "dynamic-#{region}"
93
+ options.include?(:classic) ? "dynamic-classic-#{region}" : "dynamic-#{region}"
91
94
  when :static
92
95
  options.include?(:classic) ? "static-classic-#{region}" : "static-#{region}"
93
96
  when :profile
@@ -97,10 +100,6 @@ module BlizzardApi
97
100
  end
98
101
  end
99
102
 
100
- def string_to_slug(string)
101
- CGI.escape(string.downcase.tr(' ', '-'))
102
- end
103
-
104
103
  def create_access_token
105
104
  uri = URI.parse("https://#{BlizzardApi.region}.battle.net/oauth/token")
106
105
 
@@ -120,26 +119,24 @@ module BlizzardApi
120
119
  # Creates the whole url for request
121
120
  parsed_url = URI.parse(url)
122
121
 
123
- data = options[:ignore_cache] ? nil : find_in_cache(parsed_url.to_s)
122
+ data = using_cache?(options) ? find_in_cache(parsed_url.to_s) : nil
123
+
124
124
  # If data was found that means cache is enabled and valid
125
- return format_response data if data
125
+ return JSON.parse(data, symbolize_names: true) if data
126
126
 
127
- # Override access_token
128
- @access_token = options[:access_token] if options.include? :access_token
127
+ response = consume_api parsed_url, options
129
128
 
130
- response = consume_api parsed_url
129
+ save_in_cache parsed_url.to_s, response.body, options[:ttl] || CACHE_DAY if using_cache? options
131
130
 
132
- unless options[:ignore_cache]
133
- ttl = options[:ttl] || CACHE_DAY
134
- save_in_cache parsed_url.to_s, response.body, ttl
135
- end
131
+ response_data = response.code.to_i.eql?(304) ? nil : JSON.parse(response.body, symbolize_names: true)
132
+ return [response, response_data] if mode.eql? :extended
136
133
 
137
- format_response response.body
134
+ response_data
138
135
  end
139
136
 
140
137
  def api_request(uri, query_string = {})
141
138
  # List of request options
142
- options_key = %i[ignore_cache ttl format access_token namespace classic]
139
+ options_key = %i[ignore_cache ttl format access_token namespace classic headers since]
143
140
 
144
141
  # Separates request options from api fields and options. Any user-defined option will be treated as api field.
145
142
  options = query_string.select { |k, _v| query_string.delete(k) || true if options_key.include? k }
@@ -158,35 +155,46 @@ module BlizzardApi
158
155
 
159
156
  private
160
157
 
161
- def consume_api(url)
158
+ ##
159
+ # @param options [Hash] Request options
160
+ def using_cache?(options)
161
+ return false if mode.eql?(:extended) || options.key?(:since)
162
+
163
+ !options.fetch(:ignore_cache, false)
164
+ end
165
+
166
+ def consume_api(url, options = {})
162
167
  # Creates a HTTP connection and request to ensure thread safety
163
168
  http = Net::HTTP.new(url.host, url.port)
164
169
  http.use_ssl = true
165
170
  request = Net::HTTP::Get.new(url)
166
171
 
167
- # Blizzard API documentation states the preferred way to send the access_token is using Bearer token on header
168
- request['Authorization'] = "Bearer #{@access_token}"
172
+ add_headers request, options
169
173
 
170
174
  # Executes the request
171
175
  http.request(request).tap do |response|
172
- raise BlizzardApi::ApiException.new 'Request failed', response.code.to_i unless response.code.to_i == 200
176
+ if mode.eql?(:regular) && ![200, 304].include?(response.code.to_i)
177
+ raise BlizzardApi::ApiException.new 'Request failed', response.code.to_i
178
+ end
173
179
  end
174
180
  end
175
181
 
176
- def save_in_cache(resource_url, data, ttl)
177
- return nil unless BlizzardApi.use_cache
182
+ def add_headers(request, options)
183
+ # Blizzard API documentation states the preferred way to send the access_token is using Bearer token on header
184
+ request['Authorization'] = "Bearer #{options.fetch(:access_token, @access_token)}"
185
+ # Format If-modified-since option
186
+ request['If-Modified-Since'] = options[:since].httpdate if options.key? :since
187
+ options[:headers]&.each { |header, content| request[header] = content }
188
+ end
178
189
 
179
- @redis.setex resource_url, ttl, data
190
+ def save_in_cache(resource_url, data, ttl)
191
+ @redis.setex resource_url, ttl, data if BlizzardApi.use_cache
180
192
  end
181
193
 
182
194
  def find_in_cache(resource_url)
183
195
  return false unless BlizzardApi.use_cache
184
196
 
185
- @redis.get resource_url if @redis.exists resource_url
186
- end
187
-
188
- def format_response(data)
189
- JSON.parse(data, symbolize_names: true)
197
+ @redis.get resource_url if @redis.exists? resource_url
190
198
  end
191
199
  end
192
200
  end