warcraft 0.1.0 → 0.1.1

Sign up to get free protection for your applications and to get access to all the features.
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