warcraft 0.1.0 → 0.1.1

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: f8023f3f1c59ce6ca630b2c07d53e17ed032e7d40592a9636d27f0eb99665c09
4
- data.tar.gz: 8b0f879bf9b60972701c91496e211c3d4558423ce60cfb7d198ecb404ebf80f7
3
+ metadata.gz: 4e6cd59e79952a7c3ef82293bb38e1dbc2e79a807b1d265f7645f939a333c781
4
+ data.tar.gz: 533407e86969d4af218138c34aac2a28492a08af24304c18447a7b2628e4925b
5
5
  SHA512:
6
- metadata.gz: d4df3a267d426e6b23f6df371589df55ad48dad59ac126a5a7cb3fab0227436c60b177d92e45cdd2891c5b5cb37047776b052b40ddb19c11de9239f0910ee995
7
- data.tar.gz: 829cba103df9e690e929c1ef1a4133f92d36b06888b5608ba70ae4edad468bae37848587d5e10558d1603c037fab1722a5ec9e15d2827180ecae578761bee630
6
+ metadata.gz: 45a39d55feef646f819327a3a34fa8dfef0b9cc7a1d4f59416b6f67c47635ca6a51651104bc9d08a9bdd874e354e890d214372fcddfeb8d3533573ab642af46e
7
+ data.tar.gz: d80a06ac5defa67de32677a33edaabf28b5dd0891c35227b88a08763413aa262cf508180e540b58fd73e9e5748fdf539d6dcff861a4aa82a49c1ce52758ac5e7
data/.rubocop.yml CHANGED
@@ -1,6 +1,9 @@
1
1
  AllCops:
2
2
  TargetRubyVersion: 2.5
3
3
 
4
+ Style/Documentation:
5
+ Enabled: false
6
+
4
7
  Style/StringLiterals:
5
8
  Enabled: true
6
9
  EnforcedStyle: double_quotes
data/README.md CHANGED
@@ -1,5 +1,7 @@
1
1
  # Warcraft
2
2
 
3
+ [![Gem Version](https://badge.fury.io/rb/warcraft.svg)](https://badge.fury.io/rb/warcraft)
4
+
3
5
  Welcome to your new gem! In this directory, you'll find the files you need to be able to package up your Ruby library into a gem. Put your Ruby code in the file `lib/warcraft`. To experiment with that code, run `bin/console` for an interactive prompt.
4
6
 
5
7
  TODO: Delete this and the text above, and describe your gem
data/gems.locked CHANGED
@@ -1,14 +1,20 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- warcraft (0.1.0)
5
- httparty
4
+ warcraft (0.1.1)
5
+ httparty (~> 0.18)
6
+ zeitwerk (~> 2.4)
6
7
 
7
8
  GEM
8
9
  remote: https://rubygems.org/
9
10
  specs:
11
+ addressable (2.7.0)
12
+ public_suffix (>= 2.0.2, < 5.0)
10
13
  ast (2.4.2)
14
+ crack (0.4.5)
15
+ rexml
11
16
  diff-lcs (1.4.4)
17
+ hashdiff (1.0.1)
12
18
  httparty (0.18.1)
13
19
  mime-types (~> 3.0)
14
20
  multi_xml (>= 0.5.2)
@@ -19,6 +25,7 @@ GEM
19
25
  parallel (1.20.1)
20
26
  parser (3.0.0.0)
21
27
  ast (~> 2.4.1)
28
+ public_suffix (4.0.6)
22
29
  rainbow (3.0.0)
23
30
  rake (13.0.3)
24
31
  regexp_parser (2.1.1)
@@ -49,8 +56,14 @@ GEM
49
56
  parser (>= 2.7.1.5)
50
57
  ruby-progressbar (1.11.0)
51
58
  unicode-display_width (1.7.0)
59
+ webmock (3.12.1)
60
+ addressable (>= 2.3.6)
61
+ crack (>= 0.3.2)
62
+ hashdiff (>= 0.4.0, < 2.0.0)
63
+ zeitwerk (2.4.2)
52
64
 
53
65
  PLATFORMS
66
+ x86_64-darwin-20
54
67
  x86_64-linux
55
68
 
56
69
  DEPENDENCIES
@@ -58,6 +71,7 @@ DEPENDENCIES
58
71
  rspec (~> 3.0)
59
72
  rubocop (~> 0.80)
60
73
  warcraft!
74
+ webmock
61
75
 
62
76
  BUNDLED WITH
63
77
  2.2.4
data/gems.rb CHANGED
@@ -10,3 +10,5 @@ gem "rake", "~> 13.0"
10
10
  gem "rspec", "~> 3.0"
11
11
 
12
12
  gem "rubocop", "~> 0.80"
13
+
14
+ gem "webmock"
data/lib/warcraft.rb CHANGED
@@ -1,6 +1,8 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require_relative "warcraft/version"
3
+ require "zeitwerk"
4
+ loader = Zeitwerk::Loader.for_gem
5
+ loader.setup
4
6
 
5
7
  module Warcraft
6
8
  class Error < StandardError; end
@@ -0,0 +1,41 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Warcraft
4
+ module Account
5
+ # @!method id
6
+ # @return [Integer] Blizzard Battle.net Account ID
7
+ class Profile < ApiRequest
8
+ def collections
9
+ link
10
+ end
11
+
12
+ def wow_accounts
13
+ @wow_accounts ||= WowAccount.new(@client, @response[:wow_accounts])
14
+ end
15
+
16
+ def all_characters
17
+ @response[:wow_accounts].map(:characters).flatten.map do |c|
18
+ Fragments::AccountCharacterFragment.new(@client, c)
19
+ end
20
+ end
21
+ end
22
+
23
+ class WowAccount
24
+ def initialize(client, data)
25
+ @client = client
26
+ @data = data
27
+ end
28
+
29
+ # The WoW account ID
30
+ # @return [Integer]
31
+ def id
32
+ @data[:id]
33
+ end
34
+
35
+ # @return [Array<Warcraft::Fragments::AccountCharacterFragment>]
36
+ def characters
37
+ @characters ||= @data[:characters].map { |c| Fragments::AccountCharacterFragment.new(@client, c) }
38
+ end
39
+ end
40
+ end
41
+ end
@@ -0,0 +1,31 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Warcraft
4
+ class AccountRequest < ApiRequest
5
+ # @param [Warcraft::Client] client
6
+ def initialize(client, region, token)
7
+ super(client, region)
8
+ @token = token
9
+ end
10
+
11
+ def profile
12
+ Account::Profile.new(@client, get("/profile/user/wow"))
13
+ end
14
+
15
+ def protected_character
16
+ # TODO
17
+ end
18
+
19
+ def collections
20
+ # TODO
21
+ end
22
+
23
+ def mounts
24
+ # TODO
25
+ end
26
+
27
+ def pets
28
+ # TODO
29
+ end
30
+ end
31
+ end
@@ -2,17 +2,14 @@
2
2
 
3
3
  module Warcraft
4
4
  class ApiRequest
5
- def initialize(client)
6
- super
5
+ def initialize(client, region)
7
6
  @client = client
7
+ @region = region
8
8
  end
9
9
 
10
- def get(url)
11
- @client.get(@region, "#{url}?namespace=#{namespace}")
12
- end
13
-
14
- def namespace
15
- "profile-#{@region}"
10
+ def get(url, region: nil, token: nil, namespace: "profile-#{region}")
11
+ region ||= @region
12
+ @client.get("#{url}?namespace=#{namespace}", region: region, token: token)
16
13
  end
17
14
  end
18
15
  end
@@ -1,6 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require "ostruct"
4
3
  require "forwardable"
5
4
 
6
5
  module Warcraft
@@ -10,8 +9,27 @@ module Warcraft
10
9
  def_delegator :@response, :[], :method_missing
11
10
 
12
11
  # @param [Hash] response A parsed character profile document
13
- def initialize(response)
12
+ def initialize(client, response)
13
+ @client = client
14
14
  @response = response
15
+ @memoized_responses = {}
16
+ end
17
+
18
+ # @return [String]
19
+ def url
20
+ @response.dig(:_links, :self, :href)
21
+ end
22
+
23
+ # @return [Time]
24
+ def self.convert_time(timestamp)
25
+ Time.at(timestamp / 1000)
26
+ end
27
+
28
+ protected
29
+
30
+ def link
31
+ resource_name = caller_locations(1, 1)[0].label.to_sym
32
+ @memoized_responses[resource_name] ||= @client.get(@response.dig(resource_name, :href))
15
33
  end
16
34
  end
17
35
  end
@@ -0,0 +1,163 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Warcraft
4
+ module Character
5
+ class Achievements < ApiResponse
6
+ def total_quantity
7
+ @response[:total_quantity]
8
+ end
9
+
10
+ def total_points
11
+ @response[:total_points]
12
+ end
13
+
14
+ # @return [Array<AchievementFragment>]
15
+ def achievements
16
+ @achievements ||= @response[:achievements].map { |a| AchievementFragment.new(@client, a) }
17
+ end
18
+
19
+ # @return [Array<CategoryProgress>]
20
+ def category_progress
21
+ @category_progress ||= @response[:category_progress].map { |c| CategoryProgress.new(@client, c) }
22
+ end
23
+
24
+ # @return [Array<AchievementEvent>]
25
+ def recent_events
26
+ @recent_events ||= @response[:recent_events].map { |e| AchievementEvent.new(@client, e) }
27
+ end
28
+
29
+ # @return [Warcraft::Fragments::CharacterFragment]
30
+ def character
31
+ @character ||= CharacterFragment.new(@client, @response[:character])
32
+ end
33
+
34
+ def statistics
35
+ link
36
+ end
37
+ end
38
+
39
+ class AchievementFragment
40
+ def initialize(client, data)
41
+ @client = client
42
+ @data = data
43
+ end
44
+
45
+ # @return [Integer]
46
+ def id
47
+ @data[:id]
48
+ end
49
+
50
+ # @return [String]
51
+ def name
52
+ @data.dig(:achievement, :name)
53
+ end
54
+
55
+ # @return [String]
56
+ def url
57
+ @data.dig(:achievement, :key, :href)
58
+ end
59
+
60
+ def full_achievement
61
+ @client.get(url)
62
+ end
63
+
64
+ # @return [Hash]
65
+ def criteria
66
+ @data[:criteria]
67
+ end
68
+
69
+ # @return [Boolean]
70
+ def child_criteria?
71
+ @data[:criteria].key? :child_criteria
72
+ end
73
+
74
+ # @return [Array<Hash>]
75
+ def child_criteria
76
+ has_child_criteria? ? @data.dig(:criteria, :child_criteria) : []
77
+ end
78
+
79
+ # @return [Integer]
80
+ def criteria_id
81
+ @data.dig(:criteria, :id)
82
+ end
83
+
84
+ # @return [Boolean]
85
+ def completed?
86
+ @data.dig(:criteria, :is_completed)
87
+ end
88
+
89
+ # @return [Time]
90
+ def completed_at
91
+ ApiResponse.convert_time(@data[:completed_timestamp])
92
+ end
93
+ end
94
+
95
+ class CategoryProgress
96
+ def initialize(client, data)
97
+ @client = client
98
+ @data = data
99
+ end
100
+
101
+ # @return [Integer]
102
+ def quantity
103
+ @data[:quantity]
104
+ end
105
+
106
+ # @return [Integer]
107
+ def points
108
+ @data[:points]
109
+ end
110
+
111
+ # @return [Hash]
112
+ def name
113
+ @data.dig(:category, :name)
114
+ end
115
+
116
+ # @return [Hash]
117
+ def category
118
+ @data[:category]
119
+ end
120
+
121
+ def full_category
122
+ @client.get(category_url)
123
+ end
124
+
125
+ # @return [Integer]
126
+ def category_id
127
+ @data.dig(:category, :id)
128
+ end
129
+
130
+ # @return [String]
131
+ def category_url
132
+ @data.dig(:category, :key, :href)
133
+ end
134
+ end
135
+
136
+ class AchievementEvent
137
+ def initialize(client, data)
138
+ @client = client
139
+ @data = data
140
+ end
141
+
142
+ # @return [String]
143
+ def achievement_url
144
+ @data.dig(:achievement, :key, :href)
145
+ end
146
+
147
+ # @return [String]
148
+ def achievement_name
149
+ @data.dig(:achievement, :name)
150
+ end
151
+
152
+ # @return [Integer]
153
+ def achievement_id
154
+ @data.dig(:achievement, :id)
155
+ end
156
+
157
+ # @return [Time]
158
+ def time
159
+ ApiResponse.convert_time(@data[:timestamp])
160
+ end
161
+ end
162
+ end
163
+ end
@@ -1,7 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require_relative "../api_response"
4
-
5
3
  module Warcraft
6
4
  module Character
7
5
  # @!method id
@@ -22,12 +20,71 @@ module Warcraft
22
20
  # @return [Integer]
23
21
  class Profile < ApiResponse
24
22
  def last_login
25
- Time.at(last_login_timestamp)
23
+ ApiResponse.convert_time(last_login_timestamp)
24
+ end
25
+
26
+ def achievements
27
+ link
28
+ end
29
+
30
+ def titles
31
+ link
32
+ end
33
+
34
+ def pvp_summary
35
+ link
36
+ end
37
+
38
+ def encounters
39
+ link
40
+ end
41
+
42
+ def media
43
+ link
44
+ end
45
+
46
+ def hunter_pets
47
+ link
48
+ end
49
+
50
+ def specializations
51
+ link
52
+ end
53
+
54
+ def statistics
55
+ link
56
+ end
57
+
58
+ def mythic_keystone_profile
59
+ link
60
+ end
61
+
62
+ def equipment
63
+ link
64
+ end
65
+
66
+ def appearance
67
+ link
68
+ end
69
+
70
+ def collections
71
+ link
72
+ end
73
+
74
+ def reputations
75
+ link
76
+ end
77
+
78
+ def quests
79
+ link
80
+ end
81
+
82
+ def achievements_statistics
83
+ link
26
84
  end
27
85
 
28
- # @return [String]
29
- def url
30
- @response.dig(:_links, :self, :href)
86
+ def professions
87
+ link
31
88
  end
32
89
  end
33
90
  end
@@ -4,14 +4,18 @@ module Warcraft
4
4
  class CharacterRequest < ApiRequest
5
5
  # @param [Warcraft::Client] client
6
6
  def initialize(client, region, realm, character_name)
7
- super(client)
8
- @region = region
7
+ super(client, region)
9
8
  @realm = realm
10
9
  @name = character_name
11
10
  end
12
11
 
13
12
  def profile
14
- Character::Profile.new get("/profile/wow/character/#{@realm}/#{@name}")
13
+ Character::Profile.new(@client, get("/profile/wow/character/#{@realm}/#{@name}", region: @region))
14
+ end
15
+
16
+ def achievements
17
+ Character::Achievements.new(@client, get("/profile/wow/character/#{@realm}/#{@name}/achievements",
18
+ region: @region))
15
19
  end
16
20
  end
17
21
  end
@@ -1,8 +1,10 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require "httparty"
4
+
3
5
  module Warcraft
4
6
  class Client
5
- using StringUtils
7
+ using Refinements::StringUtils
6
8
 
7
9
  attr_accessor :token, :region
8
10
 
@@ -13,11 +15,12 @@ module Warcraft
13
15
  self.region = region
14
16
  end
15
17
 
16
- # @param [Symbol] region
17
18
  # @param [String] url
19
+ # @param [Symbol] region
18
20
  # @return [Hash]
19
- def get(region, url)
20
- response = HTTParty.get("https://#{region}.api.blizzard.com#{url}",
21
+ def get(url, region = nil, token = self.token)
22
+ token = self.token if token.nil?
23
+ response = HTTParty.get(region.nil? ? url : "https://#{region}.api.blizzard.com#{url}",
21
24
  headers: {
22
25
  'Authorization': "Bearer #{token}"
23
26
  }, format: :plain)
@@ -25,7 +28,7 @@ module Warcraft
25
28
  end
26
29
 
27
30
  # @param [Symbol] region Region to fetch data for (optional)
28
- def userinfo(region = nil)
31
+ def userinfo(token = self.token, region = nil)
29
32
  domain = region == :cn ? "www.battlenet.com.cn" : "#{region}.api.blizzard.com"
30
33
  response = HTTParty.get("https://#{domain}/oauth/userinfo?access_token",
31
34
  headers: {
@@ -34,7 +37,11 @@ module Warcraft
34
37
  JSON.parse(response.body, symbolize_names: true)
35
38
  end
36
39
 
37
- def character(realm, character_name, region = self.region)
40
+ def account(token: self.token, region: self.region)
41
+ AccountRequest.new(self, region, token)
42
+ end
43
+
44
+ def character(realm:, character_name:, region: self.region)
38
45
  CharacterRequest.new(self, region, realm.slugify, character_name.slugify)
39
46
  end
40
47
  end
@@ -0,0 +1,10 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Warcraft
4
+ class Fragment
5
+ def initialize(client, data)
6
+ @client = client
7
+ @data = data
8
+ end
9
+ end
10
+ end
@@ -0,0 +1,69 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Warcraft
4
+ module Fragments
5
+ class AccountCharacterFragment < Fragment
6
+ def character
7
+ link
8
+ end
9
+
10
+ def protected_character
11
+ link
12
+ end
13
+
14
+ def name
15
+ @data[:name]
16
+ end
17
+
18
+ def id
19
+ @data[:id]
20
+ end
21
+
22
+ def realm_url
23
+ @data.dig(:realm, :key, :href)
24
+ end
25
+
26
+ def realm_name
27
+ @data.dig(:realm, :name)
28
+ end
29
+
30
+ def realm_id
31
+ @data.dig(:realm, :id)
32
+ end
33
+
34
+ def realm_slug
35
+ @data.dig(:realm, :slug)
36
+ end
37
+
38
+ def playable_class_url
39
+ @data.dig(:playable_class, :key, :href)
40
+ end
41
+
42
+ def playable_class_id
43
+ @data.dig(:playable_class, :id)
44
+ end
45
+
46
+ def playable_race_url
47
+ @data.dig(:playable_race, :key, :href)
48
+ end
49
+
50
+ def playable_race_id
51
+ @data.dig(:playable_race, :id)
52
+ end
53
+
54
+ def gender
55
+ @dig.dig(:gender, :type)
56
+ end
57
+
58
+ def faction
59
+ @dig.dig(:faction, :type)
60
+ end
61
+
62
+ def level
63
+ @dig[:level]
64
+ end
65
+
66
+ # TODO: class, race, gender and faction are localised
67
+ end
68
+ end
69
+ end
@@ -0,0 +1,24 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Warcraft
4
+ module Fragments
5
+ class CharacterFragment < Fragment
6
+ # @return [String]
7
+ def url
8
+ @data.dig(:key, :href)
9
+ end
10
+
11
+ def id
12
+ @data[:id]
13
+ end
14
+
15
+ def slug
16
+ @data[:slug]
17
+ end
18
+
19
+ def realm
20
+ # TODO: Localised resource
21
+ end
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,13 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Warcraft
4
+ module Refinements
5
+ module StringUtils
6
+ refine String do
7
+ def slugify
8
+ downcase.gsub(" ", "-")
9
+ end
10
+ end
11
+ end
12
+ end
13
+ end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Warcraft
4
- VERSION = "0.1.0"
4
+ VERSION = "0.1.1"
5
5
  end
data/warcraft.gemspec CHANGED
@@ -24,7 +24,8 @@ Gem::Specification.new do |spec|
24
24
  end
25
25
  spec.require_paths = ["lib"]
26
26
 
27
- spec.add_dependency "httparty"
27
+ spec.add_dependency "httparty", "~> 0.18"
28
+ spec.add_dependency "zeitwerk", "~> 2.4"
28
29
 
29
30
  # For more information and examples about making a new gem, checkout our
30
31
  # guide at: https://bundler.io/guides/creating_gem.html
metadata CHANGED
@@ -1,29 +1,43 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: warcraft
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 0.1.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Karina Kwiatek
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2021-03-05 00:00:00.000000000 Z
11
+ date: 2021-03-07 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: httparty
15
15
  requirement: !ruby/object:Gem::Requirement
16
16
  requirements:
17
- - - ">="
17
+ - - "~>"
18
18
  - !ruby/object:Gem::Version
19
- version: '0'
19
+ version: '0.18'
20
20
  type: :runtime
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
- - - ">="
24
+ - - "~>"
25
25
  - !ruby/object:Gem::Version
26
- version: '0'
26
+ version: '0.18'
27
+ - !ruby/object:Gem::Dependency
28
+ name: zeitwerk
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '2.4'
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '2.4'
27
41
  description:
28
42
  email:
29
43
  - racc@raccube.net
@@ -44,14 +58,20 @@ files:
44
58
  - bin/setup
45
59
  - gems.locked
46
60
  - gems.rb
47
- - lib/refinements/string_utils.rb
48
61
  - lib/warcraft.rb
62
+ - lib/warcraft/account/profile.rb
63
+ - lib/warcraft/account_request.rb
49
64
  - lib/warcraft/api_request.rb
50
65
  - lib/warcraft/api_response.rb
66
+ - lib/warcraft/character/achievements.rb
51
67
  - lib/warcraft/character/profile.rb
52
68
  - lib/warcraft/character_request.rb
69
+ - lib/warcraft/client.rb
70
+ - lib/warcraft/fragment.rb
71
+ - lib/warcraft/fragments/account_character_fragment.rb
72
+ - lib/warcraft/fragments/character_fragment.rb
73
+ - lib/warcraft/refinements/string_utils.rb
53
74
  - lib/warcraft/version.rb
54
- - lib/warcraft/warcraft_client.rb
55
75
  - warcraft.gemspec
56
76
  homepage: https://github.com/raccube/warcraft
57
77
  licenses:
@@ -1,9 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module StringUtils
4
- refine String do
5
- def slugify
6
- downcase.gsub(" ", "-")
7
- end
8
- end
9
- end