restiny 0.6.1 → 2.0.0

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: b9250ce97e7698687ee6cc64362dc0ff0cfe222115a544f60290dbccbfa4255b
4
+ data.tar.gz: a33846e9b1a017a1a357f0ea51aeaa74f71d296d02f61f1a1da68a89bcf90498
5
5
  SHA512:
6
- metadata.gz: 495d10b083c4fcb3b8ff6697db0e206abab20e1b0fead5549f5b4d9a7fc467343eb82dcaef07e4fdece7590d392f3144e3eb25f2c23ed27740c7118fc7f25294
7
- data.tar.gz: 64972701dd9a41ec8f835b8e4443d39020c097662ac98d7f50d08e7ae92997ea159c21a8a9d83c296fd04a330b4a7d395cb2c43651fe9bd87345cef2f5d303eb
6
+ metadata.gz: 06d7bfcdd5a4263a4ac1db64ab4c55bf6986378fe5fa1a592616a2d03662f15f3cce91398b40a2fe3a03e2950c9eb8005bc64202980d1c4d41c4be54c82014d7
7
+ data.tar.gz: 7ec6297618ebaa28d3ef6f1ba5b96761a7beb04911201c2f80dd63aa671b48a072d0df9d4e26525ec962379245cbed3ff2d404b8d78efc541233eb0d9d8e12a4
@@ -0,0 +1,34 @@
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?
11
+
12
+ payload = JSON.parse(env["response_body"])
13
+ if payload["ErrorCode"] == 1
14
+ env[:body] = payload.dig("Response")
15
+ return
16
+ end
17
+
18
+ klass =
19
+ case env["status"]
20
+ when 400..499
21
+ ::Restiny::RequestError
22
+ when 500..599
23
+ ::Restiny::ResponseError
24
+ else
25
+ ::Restiny::Error
26
+ end
27
+
28
+ raise klass.new(payload["Message"], payload["ErrorStatus"])
29
+ rescue JSON::ParserError
30
+ raise ::Restiny::ResponseError.new("Unable to parse API response")
31
+ end
32
+ end
33
+ end
34
+ 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.0"
5
5
  end
data/lib/restiny.rb CHANGED
@@ -9,6 +9,7 @@ require "restiny/manifest"
9
9
 
10
10
  require "faraday"
11
11
  require "faraday/follow_redirects"
12
+ require "faraday/destiny/api"
12
13
  require "securerandom"
13
14
 
14
15
  module Restiny
@@ -21,7 +22,7 @@ module Restiny
21
22
 
22
23
  # OAuth methods
23
24
 
24
- def authorise_url(redirect_url = nil, state = nil)
25
+ def get_authorise_url(redirect_url: nil, state: nil)
25
26
  check_oauth_client_id
26
27
 
27
28
  @oauth_state = state || SecureRandom.hex(15)
@@ -32,126 +33,117 @@ module Restiny
32
33
  connection.build_url(BUNGIE_URL + "/en/oauth/authorize", params).to_s
33
34
  end
34
35
 
35
- def request_access_token(code, redirect_url = nil)
36
+ def request_access_token(code:, redirect_url: nil)
36
37
  check_oauth_client_id
37
38
 
38
39
  params = { code: code, grant_type: "authorization_code", client_id: @oauth_client_id }
39
40
  params[:redirect_url] = redirect_url unless redirect_url.nil?
40
41
 
41
- make_api_request(
42
- :post,
43
- "app/oauth/token/",
42
+ connection.post(
43
+ "app/oauth/token",
44
44
  params,
45
45
  "Content-Type" => "application/x-www-form-urlencoded"
46
- )
46
+ ).body
47
47
  end
48
48
 
49
49
  # Manifest methods
50
50
 
51
- def download_manifest(locale = "en")
52
- response = get("Destiny2/Manifest/")
51
+ def get_manifest_url(locale: "en")
52
+ result = connection.get("Destiny2/Manifest/").body.dig("mobileWorldContentPaths", locale)
53
+ BUNGIE_URL + result
54
+ end
53
55
 
54
- manifest_path = response.dig("mobileWorldContentPaths", locale)
55
- raise Restiny::ResponseError.new("Unable to determine manifest URL") if manifest_path.nil?
56
+ def download_manifest(locale: "en")
57
+ manifest_url = get_manifest_url
58
+ raise Restiny::ResponseError.new("Unable to determine manifest URL") if manifest_url.nil?
56
59
 
57
- Manifest.download(BUNGIE_URL + manifest_path)
60
+ Manifest.download_by_url(BUNGIE_URL + manifest_url)
58
61
  end
59
62
 
60
- # Profile methods
63
+ # Profile and related methods
61
64
 
62
- def get_profile(membership_id, membership_type, components = [])
63
- if components.empty?
65
+ def get_profile(membership_id:, membership_type:, components:, type_url: nil)
66
+ if !components.is_a?(Array) || components.empty?
64
67
  raise Restiny::InvalidParamsError.new("Please provide at least one component")
65
68
  end
66
69
 
67
- get("Destiny2/#{membership_type}/Profile/#{membership_id}?components=#{components.join(",")}")
70
+ url = "Destiny2/#{membership_type}/Profile/#{membership_id}/"
71
+ url += type_url if type_url
72
+ url += "?components=#{components.join(",")}"
73
+
74
+ connection.get(url).body
75
+ end
76
+
77
+ def get_character_profile(character_id:, membership_id:, membership_type:, components:)
78
+ get_profile(
79
+ membership_id: membership_id,
80
+ membership_type: membership_type,
81
+ components: components,
82
+ type_url: "Character/#{character_id}"
83
+ )
84
+ end
85
+
86
+ def get_instanced_item_profile(item_id:, membership_id:, membership_type:, components:)
87
+ get_profile(
88
+ membership_id: membership_id,
89
+ membership_type: membership_type,
90
+ components: components,
91
+ type_url: "Item/#{item_id}"
92
+ )
68
93
  end
69
94
 
70
- # Account methods
95
+ # User methods.
71
96
 
72
- def get_user_by_membership_id(membership_id, membership_type = Platform::ALL)
97
+ def get_user_memberships_by_id(membership_id, membership_type: Platform::ALL)
73
98
  raise Restiny::InvalidParamsError.new("Please provide a membership ID") if membership_id.nil?
74
99
 
75
- get("User/GetMembershipsById/#{membership_id}/#{membership_type}/")
100
+ connection.get("User/GetMembershipsById/#{membership_id}/#{membership_type}/").body
76
101
  end
77
102
 
78
- def get_user_by_bungie_name(full_display_name, membership_type = Platform::ALL)
79
- display_name, display_name_code = full_display_name.split("#")
103
+ def search_player_by_bungie_name(name, membership_type: Platform::ALL)
104
+ display_name, display_name_code = name.split("#")
80
105
  if display_name.nil? || display_name_code.nil?
81
106
  raise Restiny::InvalidParamsError.new("You must provide a valid Bungie name")
82
107
  end
83
108
 
84
- post(
109
+ connection.post(
85
110
  "Destiny2/SearchDestinyPlayerByBungieName/#{membership_type}/",
86
- { displayName: display_name, displayNameCode: display_name_code }
87
- )
111
+ displayName: display_name,
112
+ displayNameCode: display_name_code
113
+ ).body
88
114
  end
89
115
 
90
- def search_users(name, page = 0)
91
- post("User/Search/GlobalName/#{page}", displayNamePrefix: name)
116
+ def search_users_by_global_name(name:, page: 0)
117
+ connection.post("User/Search/GlobalName/#{page}", displayNamePrefix: name).body
92
118
  end
93
119
 
94
- def get(endpoint_url, params = {}, headers = {})
95
- make_api_request(:get, endpoint_url, params, headers).dig("Response")
96
- end
97
-
98
- def post(endpoint_url, body, headers = {})
99
- make_api_request(:post, endpoint_url, body, headers).dig("Response")
100
- end
120
+ # General request methods
101
121
 
102
122
  private
103
123
 
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
135
-
136
- raise klass.new(message, status)
137
- end
138
-
139
124
  def check_oauth_client_id
140
125
  raise Restiny::RequestError.new("You need to set an OAuth client ID") unless @oauth_client_id
141
126
  end
142
127
 
143
128
  def default_headers
144
- { "User-Agent": "restiny v#{Restiny::VERSION}", "X-API-KEY": @api_key }
129
+ {
130
+ "User-Agent": "restiny v#{Restiny::VERSION}",
131
+ "X-API-KEY": @api_key,
132
+ "Content-Type": "application/json"
133
+ }
145
134
  end
146
135
 
147
136
  def connection
148
- @connection ||=
149
- Faraday.new(url: API_BASE_URL, headers: default_headers) do |faraday|
150
- faraday.request :json
151
- faraday.request :url_encoded
152
- faraday.response :json
153
- faraday.response :follow_redirects
154
- faraday.response :raise_error
155
- end
137
+ raise Restiny::InvalidParamsError.new("You need to set an API key") unless @api_key
138
+
139
+ headers = default_headers
140
+ headers["authorization"] = "Bearer #{@oauth_token}" if @oauth_token
141
+
142
+ Faraday.new(url: API_BASE_URL, headers: headers) do |faraday|
143
+ faraday.request :url_encoded
144
+ faraday.request :json
145
+ faraday.response :follow_redirects
146
+ faraday.response :destiny_api
147
+ end
156
148
  end
157
149
  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.0
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-06-30 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: faraday
@@ -157,6 +157,7 @@ executables: []
157
157
  extensions: []
158
158
  extra_rdoc_files: []
159
159
  files:
160
+ - lib/faraday/destiny/api.rb
160
161
  - lib/restiny.rb
161
162
  - lib/restiny/constants.rb
162
163
  - lib/restiny/errors.rb