restiny 0.6.1 → 2.0.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: d746d115f85cce78834085e5a291555b9f3a04591d6533b31c569bf8a8ddc161
4
- data.tar.gz: 2b7b6deb692271d86a6d0eb47217f239c97c7145154cb1ab7a04999939d943d0
3
+ metadata.gz: 2d5b81f9aadd44def19fb9af625b26692992457edaf57eeba97b46896f26e032
4
+ data.tar.gz: f058584408a167934ae67f9e8c160f75e542f80558446ee312fa2ce34b763ace
5
5
  SHA512:
6
- metadata.gz: 495d10b083c4fcb3b8ff6697db0e206abab20e1b0fead5549f5b4d9a7fc467343eb82dcaef07e4fdece7590d392f3144e3eb25f2c23ed27740c7118fc7f25294
7
- data.tar.gz: 64972701dd9a41ec8f835b8e4443d39020c097662ac98d7f50d08e7ae92997ea159c21a8a9d83c296fd04a330b4a7d395cb2c43651fe9bd87345cef2f5d303eb
6
+ metadata.gz: 5b737a79ec4728c34106b701db09f654c9d642cfd62b3ff311501a70afcf954f07ad92f0d1282c9a59686bffef568ef2b1fb5466e97cd267b389c1634c28b742
7
+ data.tar.gz: 99c7c3c4519a6a539a11a2970f18a38443ee4a9587b6df980cb74b03e425f1ce134e48c075af0d5b8d29339e086310eda6c44ac352e0b4daf80997923fded98b
@@ -0,0 +1,31 @@
1
+ require "faraday"
2
+ require "restiny/errors"
3
+
4
+ module Faraday
5
+ module Restiny
6
+ Faraday::Response.register_middleware(destiny_api: "Faraday::Restiny::Api")
7
+
8
+ class Api < Middleware
9
+ def on_complete(env)
10
+ return if env["response_body"].empty? || !env["response_body"].dig("ErrorCode")
11
+
12
+ if env["response_body"]["ErrorCode"] == 1
13
+ env[:body] = env["response_body"].dig("Response")
14
+ return
15
+ end
16
+
17
+ klass =
18
+ case env["status"]
19
+ when 400..499
20
+ ::Restiny::RequestError
21
+ when 500..599
22
+ ::Restiny::ResponseError
23
+ else
24
+ ::Restiny::Error
25
+ end
26
+
27
+ raise klass.new(env["response_body"]["Message"], env["response_body"]["ErrorStatus"])
28
+ end
29
+ end
30
+ end
31
+ end
@@ -0,0 +1,21 @@
1
+ require "faraday"
2
+ require "restiny/errors"
3
+
4
+ module Faraday
5
+ module Restiny
6
+ Faraday::Response.register_middleware(destiny_auth: "Faraday::Restiny::Auth")
7
+
8
+ class Auth < Middleware
9
+ def on_complete(env)
10
+ return if env["response_body"].empty? || env["url"].to_s !~ /oauth/
11
+
12
+ if env["response_body"]["error"]
13
+ raise ::Restiny::AuthenticationError.new(
14
+ env["response_body"]["error_description"],
15
+ env["response_body"]["error"]
16
+ )
17
+ end
18
+ end
19
+ end
20
+ end
21
+ end
@@ -40,4 +40,32 @@ module Restiny
40
40
  SUPERIOR = 5
41
41
  EXOTIC = 6
42
42
  end
43
+
44
+ module Class
45
+ TITAN = 0
46
+ HUNTER = 1
47
+ WARLOCK = 2
48
+ UNKNOWN = 3
49
+ end
50
+
51
+ module Race
52
+ HUMAN = 0
53
+ AWOKEN = 1
54
+ EXO = 2
55
+ UNKNOWN = 3
56
+ end
57
+
58
+ module Gender
59
+ MASCULINE = 0
60
+ FEMININE = 1
61
+ UNKNOWN = 2
62
+ end
63
+
64
+ module Ammunition
65
+ NONE = 0
66
+ PRIMARY = 1
67
+ SPECIAL = 2
68
+ HEAVY = 3
69
+ UNKNOWN = 4
70
+ end
43
71
  end
@@ -17,6 +17,9 @@ module Restiny
17
17
  class RateLimitedError < RequestError
18
18
  end
19
19
 
20
+ class AuthenticationError < RequestError
21
+ end
22
+
20
23
  class ResponseError < Error
21
24
  end
22
25
  end
@@ -79,15 +79,15 @@ module Restiny
79
79
  single_method_name, plural_method_name = method_names
80
80
 
81
81
  define_method single_method_name do |id|
82
- fetch_item(full_table_name, id)
82
+ fetch_item(table_name: full_table_name, id: id)
83
83
  end
84
84
 
85
- define_method plural_method_name do |limit = nil|
86
- fetch_items(full_table_name, limit)
85
+ define_method plural_method_name do |limit: nil|
86
+ fetch_items(table_name: full_table_name, limit: limit)
87
87
  end
88
88
  end
89
89
 
90
- def self.download(url)
90
+ def self.download_by_url(url)
91
91
  zipped_file = Down.download(url)
92
92
  manifest_path = zipped_file.path + ".db"
93
93
 
@@ -116,7 +116,7 @@ module Restiny
116
116
  @database.execute(query).map { |row| row["name"].gsub(/(Destiny|Definition)/, "") }
117
117
  end
118
118
 
119
- def fetch_item(table_name, id)
119
+ def fetch_item(table_name:, id:)
120
120
  query = "SELECT json FROM #{table_name} WHERE json_extract(json, '$.hash')=?"
121
121
  result = @database.execute(query, id)
122
122
 
@@ -127,7 +127,7 @@ module Restiny
127
127
  raise Restiny::RequestError.new("Error while fetching item (#{e})")
128
128
  end
129
129
 
130
- def fetch_items(table_name, limit = nil)
130
+ def fetch_items(table_name:, limit: nil)
131
131
  bindings = []
132
132
 
133
133
  query = "SELECT json FROM #{table_name} ORDER BY json_extract(json, '$.index')"
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Restiny
4
- VERSION = "0.6.1"
4
+ VERSION = "2.0.1"
5
5
  end
data/lib/restiny.rb CHANGED
@@ -9,6 +9,8 @@ require "restiny/manifest"
9
9
 
10
10
  require "faraday"
11
11
  require "faraday/follow_redirects"
12
+ require "faraday/destiny/api"
13
+ require "faraday/destiny/auth"
12
14
  require "securerandom"
13
15
 
14
16
  module Restiny
@@ -21,7 +23,7 @@ module Restiny
21
23
 
22
24
  # OAuth methods
23
25
 
24
- def authorise_url(redirect_url = nil, state = nil)
26
+ def get_authorise_url(redirect_url: nil, state: nil)
25
27
  check_oauth_client_id
26
28
 
27
29
  @oauth_state = state || SecureRandom.hex(15)
@@ -29,129 +31,142 @@ module Restiny
29
31
  params = { response_type: "code", client_id: @oauth_client_id, state: @oauth_state }
30
32
  params[:redirect_url] = redirect_url unless redirect_url.nil?
31
33
 
32
- connection.build_url(BUNGIE_URL + "/en/oauth/authorize", params).to_s
34
+ auth_connection.build_url(BUNGIE_URL + "/en/oauth/authorize/", params).to_s
33
35
  end
34
36
 
35
- def request_access_token(code, redirect_url = nil)
37
+ def request_access_token(code:, redirect_url: nil)
36
38
  check_oauth_client_id
37
39
 
38
40
  params = { code: code, grant_type: "authorization_code", client_id: @oauth_client_id }
39
41
  params[:redirect_url] = redirect_url unless redirect_url.nil?
40
42
 
41
- make_api_request(
42
- :post,
43
- "app/oauth/token/",
44
- params,
45
- "Content-Type" => "application/x-www-form-urlencoded"
46
- )
43
+ auth_post("app/oauth/token/", params)
47
44
  end
48
45
 
49
46
  # Manifest methods
50
47
 
51
- def download_manifest(locale = "en")
52
- response = get("Destiny2/Manifest/")
48
+ def get_manifest_url(locale: "en")
49
+ result = api_get("Destiny2/Manifest/").dig("mobileWorldContentPaths", locale)
50
+ BUNGIE_URL + result
51
+ end
53
52
 
54
- manifest_path = response.dig("mobileWorldContentPaths", locale)
55
- raise Restiny::ResponseError.new("Unable to determine manifest URL") if manifest_path.nil?
53
+ def download_manifest(locale: "en")
54
+ manifest_url = get_manifest_url
55
+ raise Restiny::ResponseError.new("Unable to determine manifest URL") if manifest_url.nil?
56
56
 
57
- Manifest.download(BUNGIE_URL + manifest_path)
57
+ Manifest.download_by_url(BUNGIE_URL + manifest_url)
58
58
  end
59
59
 
60
- # Profile methods
60
+ # Profile and related methods
61
61
 
62
- def get_profile(membership_id, membership_type, components = [])
63
- if components.empty?
62
+ def get_profile(membership_id:, membership_type:, components:, type_url: nil)
63
+ if !components.is_a?(Array) || components.empty?
64
64
  raise Restiny::InvalidParamsError.new("Please provide at least one component")
65
65
  end
66
66
 
67
- get("Destiny2/#{membership_type}/Profile/#{membership_id}?components=#{components.join(",")}")
67
+ url = "Destiny2/#{membership_type}/Profile/#{membership_id}/"
68
+ url += type_url if type_url
69
+ url += "?components=#{components.join(",")}"
70
+
71
+ api_get(url)
72
+ end
73
+
74
+ def get_character_profile(character_id:, membership_id:, membership_type:, components:)
75
+ get_profile(
76
+ membership_id: membership_id,
77
+ membership_type: membership_type,
78
+ components: components,
79
+ type_url: "Character/#{character_id}/"
80
+ )
68
81
  end
69
82
 
70
- # Account methods
83
+ def get_instanced_item_profile(item_id:, membership_id:, membership_type:, components:)
84
+ get_profile(
85
+ membership_id: membership_id,
86
+ membership_type: membership_type,
87
+ components: components,
88
+ type_url: "Item/#{item_id}/"
89
+ )
90
+ end
71
91
 
72
- def get_user_by_membership_id(membership_id, membership_type = Platform::ALL)
73
- raise Restiny::InvalidParamsError.new("Please provide a membership ID") if membership_id.nil?
92
+ # User methods.
74
93
 
75
- get("User/GetMembershipsById/#{membership_id}/#{membership_type}/")
94
+ def get_user_memberships_by_id(membership_id, membership_type: Platform::ALL)
95
+ raise Restiny::InvalidParamsError.new("Please provide a membership ID") if membership_id.nil?
96
+ api_get("User/GetMembershipsById/#{membership_id}/#{membership_type}/")
76
97
  end
77
98
 
78
- def get_user_by_bungie_name(full_display_name, membership_type = Platform::ALL)
79
- display_name, display_name_code = full_display_name.split("#")
99
+ def search_player_by_bungie_name(name, membership_type: Platform::ALL)
100
+ display_name, display_name_code = name.split("#")
80
101
  if display_name.nil? || display_name_code.nil?
81
102
  raise Restiny::InvalidParamsError.new("You must provide a valid Bungie name")
82
103
  end
83
104
 
84
- post(
105
+ api_post(
85
106
  "Destiny2/SearchDestinyPlayerByBungieName/#{membership_type}/",
86
- { displayName: display_name, displayNameCode: display_name_code }
107
+ params: {
108
+ displayName: display_name,
109
+ displayNameCode: display_name_code
110
+ }
87
111
  )
88
112
  end
89
113
 
90
- def search_users(name, page = 0)
91
- post("User/Search/GlobalName/#{page}", displayNamePrefix: name)
114
+ def search_users_by_global_name(name:, page: 0)
115
+ api_post("User/Search/GlobalName/#{page}/", params: { displayNamePrefix: name })
92
116
  end
93
117
 
94
- def get(endpoint_url, params = {}, headers = {})
95
- make_api_request(:get, endpoint_url, params, headers).dig("Response")
96
- end
118
+ # General request methods
97
119
 
98
- def post(endpoint_url, body, headers = {})
99
- make_api_request(:post, endpoint_url, body, headers).dig("Response")
120
+ def api_get(url, params: {})
121
+ api_connection.get(url, params, token_header).body
100
122
  end
101
123
 
102
- private
103
-
104
- def make_api_request(type, url, params, headers = {})
105
- raise Restiny::InvalidParamsError.new("You need to set an API key") unless @api_key
106
-
107
- headers[:authorization] = "Bearer #{@oauth_token}" if @oauth_token
108
-
109
- response =
110
- case type
111
- when :get
112
- connection.get(url, params, headers)
113
- when :post
114
- connection.post(url, params, headers)
115
- end
116
-
117
- response.body
118
- rescue Faraday::Error => error
119
- begin
120
- error_body = JSON.parse(error.response_body)
121
- status, message = error_body["ErrorStatus"], error_body["Message"]
122
- rescue JSON::ParserError
123
- status, message = error.response_status, error.message
124
- end
125
-
126
- klass =
127
- case error
128
- when Faraday::ClientError
129
- Restiny::RequestError
130
- when Faraday::ServerError
131
- Restiny::ResponseError
132
- else
133
- Restiny::Error
134
- end
124
+ def api_post(url, params: {})
125
+ api_connection.post(url, params, token_header).body
126
+ end
135
127
 
136
- raise klass.new(message, status)
128
+ def auth_post(url, params)
129
+ auth_connection.post(url, params, "Content-Type" => "application/x-www-form-urlencoded").body
137
130
  end
138
131
 
132
+ private
133
+
139
134
  def check_oauth_client_id
140
135
  raise Restiny::RequestError.new("You need to set an OAuth client ID") unless @oauth_client_id
141
136
  end
142
137
 
143
138
  def default_headers
144
- { "User-Agent": "restiny v#{Restiny::VERSION}", "X-API-KEY": @api_key }
139
+ { "User-Agent": "restiny v#{Restiny::VERSION}" }
145
140
  end
146
141
 
147
- def connection
142
+ def api_connection
143
+ raise Restiny::InvalidParamsError.new("You need to set an API key") unless @api_key
144
+
148
145
  @connection ||=
149
- Faraday.new(url: API_BASE_URL, headers: default_headers) do |faraday|
150
- faraday.request :json
146
+ Faraday.new(
147
+ url: API_BASE_URL,
148
+ headers: default_headers.merge("X-API-KEY": @api_key)
149
+ ) do |faraday|
151
150
  faraday.request :url_encoded
151
+ faraday.request :json
152
+ faraday.response :follow_redirects
153
+ faraday.response :destiny_api
152
154
  faraday.response :json
155
+ end
156
+ end
157
+
158
+ def auth_connection
159
+ @auth_connection ||=
160
+ Faraday.new(url: API_BASE_URL, headers: default_headers) do |faraday|
161
+ faraday.request :url_encoded
162
+ faraday.request :json
153
163
  faraday.response :follow_redirects
154
- faraday.response :raise_error
164
+ faraday.response :destiny_auth
165
+ faraday.response :json
155
166
  end
156
167
  end
168
+
169
+ def token_header
170
+ {}.tap { |headers| headers["authorization"] = "Bearer #{@oauth_token}" if @oauth_token }
171
+ end
157
172
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: restiny
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.6.1
4
+ version: 2.0.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Daniel Bogan
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2023-06-11 00:00:00.000000000 Z
11
+ date: 2023-07-02 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: faraday
@@ -157,6 +157,8 @@ executables: []
157
157
  extensions: []
158
158
  extra_rdoc_files: []
159
159
  files:
160
+ - lib/faraday/destiny/api.rb
161
+ - lib/faraday/destiny/auth.rb
160
162
  - lib/restiny.rb
161
163
  - lib/restiny/constants.rb
162
164
  - lib/restiny/errors.rb