spotted 0.9.0 → 0.11.0
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 +4 -4
- data/CHANGELOG.md +16 -0
- data/README.md +1 -1
- data/lib/spotted/client.rb +62 -15
- data/lib/spotted/models/audio_analysis_retrieve_response.rb +5 -0
- data/lib/spotted/version.rb +1 -1
- data/rbi/spotted/client.rbi +20 -4
- data/rbi/spotted/models/audio_analysis_retrieve_response.rbi +5 -0
- data/sig/spotted/client.rbs +10 -3
- data/sig/spotted/models/audio_analysis_retrieve_response.rbs +5 -0
- metadata +1 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 53171d2924e8b65667348df43a8315b13834283411bcc57260a3dee25ed1b5bb
|
|
4
|
+
data.tar.gz: 4a987cf805446e513e6d977a00aa999f48d64ca881e7adc6f7a3ae9352169348
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 13b3fab4d5ead1e934399769d8556ba0521e2bebcbe5a0da61fc4cefba97ebd92801afc3d4136bc70f7efea09b7a3ac0689e41e8633968d4f983d11a7f4bc1b2
|
|
7
|
+
data.tar.gz: 0ce09546710593e818c08530438f4ab6918fd9e103ad54d3376af6362da5bb197298bdec2a931cc6868259aa49eacd08a827108d4375a5075922a1295594667e
|
data/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,21 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 0.11.0 (2025-11-10)
|
|
4
|
+
|
|
5
|
+
Full Changelog: [v0.10.0...v0.11.0](https://github.com/cjavdev/spotted/compare/v0.10.0...v0.11.0)
|
|
6
|
+
|
|
7
|
+
### Features
|
|
8
|
+
|
|
9
|
+
* **api:** manual updates ([feb8221](https://github.com/cjavdev/spotted/commit/feb822194d2e961c6469ca5e36c8d0cccdb0cb5a))
|
|
10
|
+
|
|
11
|
+
## 0.10.0 (2025-11-10)
|
|
12
|
+
|
|
13
|
+
Full Changelog: [v0.9.0...v0.10.0](https://github.com/cjavdev/spotted/compare/v0.9.0...v0.10.0)
|
|
14
|
+
|
|
15
|
+
### Features
|
|
16
|
+
|
|
17
|
+
* **api:** add mode constants ([d4e1a41](https://github.com/cjavdev/spotted/commit/d4e1a411d13a43dfcd553f86a3a9e25f3f2e308e))
|
|
18
|
+
|
|
3
19
|
## 0.9.0 (2025-11-10)
|
|
4
20
|
|
|
5
21
|
Full Changelog: [v0.8.0...v0.9.0](https://github.com/cjavdev/spotted/compare/v0.8.0...v0.9.0)
|
data/README.md
CHANGED
data/lib/spotted/client.rb
CHANGED
|
@@ -15,12 +15,15 @@ module Spotted
|
|
|
15
15
|
# Default max retry delay in seconds.
|
|
16
16
|
DEFAULT_MAX_RETRY_DELAY = 8.0
|
|
17
17
|
|
|
18
|
-
# @return [String]
|
|
18
|
+
# @return [String, nil]
|
|
19
19
|
attr_reader :client_id
|
|
20
20
|
|
|
21
|
-
# @return [String]
|
|
21
|
+
# @return [String, nil]
|
|
22
22
|
attr_reader :client_secret
|
|
23
23
|
|
|
24
|
+
# @return [String, nil]
|
|
25
|
+
attr_reader :access_token
|
|
26
|
+
|
|
24
27
|
# @return [Spotted::Resources::Albums]
|
|
25
28
|
attr_reader :albums
|
|
26
29
|
|
|
@@ -69,6 +72,22 @@ module Spotted
|
|
|
69
72
|
# @return [Spotted::Resources::Markets]
|
|
70
73
|
attr_reader :markets
|
|
71
74
|
|
|
75
|
+
# @api private
|
|
76
|
+
#
|
|
77
|
+
# @return [Hash{String=>String}]
|
|
78
|
+
private def auth_headers
|
|
79
|
+
{**bearer_auth, **oauth_2_0}
|
|
80
|
+
end
|
|
81
|
+
|
|
82
|
+
# @api private
|
|
83
|
+
#
|
|
84
|
+
# @return [Hash{String=>String}]
|
|
85
|
+
private def bearer_auth
|
|
86
|
+
return {} if @access_token.nil?
|
|
87
|
+
|
|
88
|
+
{"authorization" => "Bearer #{@access_token}"}
|
|
89
|
+
end
|
|
90
|
+
|
|
72
91
|
# @api private
|
|
73
92
|
# @return [Spotted::Internal::OAuth2ClientCredentials]
|
|
74
93
|
attr_reader :oauth_2_0_state
|
|
@@ -76,7 +95,7 @@ module Spotted
|
|
|
76
95
|
# @api private
|
|
77
96
|
#
|
|
78
97
|
# @return [Hash{String=>String}]
|
|
79
|
-
private def
|
|
98
|
+
private def oauth_2_0
|
|
80
99
|
return @oauth_2_0_state.auth_headers if @oauth_2_0_state
|
|
81
100
|
|
|
82
101
|
return {} unless @client_id && @client_secret
|
|
@@ -106,6 +125,8 @@ module Spotted
|
|
|
106
125
|
#
|
|
107
126
|
# @param client_secret [String, nil] Defaults to `ENV["SPOTIFY_CLIENT_SECRET"]`
|
|
108
127
|
#
|
|
128
|
+
# @param access_token [String, nil] Defaults to `ENV["SPOTIFY_ACCESS_TOKEN"]`
|
|
129
|
+
#
|
|
109
130
|
# @param base_url [String, nil] Override the default base URL for the API, e.g.,
|
|
110
131
|
# `"https://api.example.com/v2/"`. Defaults to `ENV["SPOTTED_BASE_URL"]`
|
|
111
132
|
#
|
|
@@ -119,6 +140,7 @@ module Spotted
|
|
|
119
140
|
def initialize(
|
|
120
141
|
client_id: ENV["SPOTIFY_CLIENT_ID"],
|
|
121
142
|
client_secret: ENV["SPOTIFY_CLIENT_SECRET"],
|
|
143
|
+
access_token: ENV["SPOTIFY_ACCESS_TOKEN"],
|
|
122
144
|
base_url: ENV["SPOTTED_BASE_URL"],
|
|
123
145
|
max_retries: self.class::DEFAULT_MAX_RETRIES,
|
|
124
146
|
timeout: self.class::DEFAULT_TIMEOUT_IN_SECONDS,
|
|
@@ -127,18 +149,9 @@ module Spotted
|
|
|
127
149
|
)
|
|
128
150
|
base_url ||= "https://api.spotify.com/v1"
|
|
129
151
|
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
if client_secret.nil?
|
|
134
|
-
# Ignore Layout/LineLength
|
|
135
|
-
# rubocop:disable Layout/LineLength
|
|
136
|
-
raise ArgumentError.new("client_secret is required, and can be set via environ: \"SPOTIFY_CLIENT_SECRET\"")
|
|
137
|
-
# rubocop:enable Layout/LineLength
|
|
138
|
-
end
|
|
139
|
-
|
|
140
|
-
@client_id = client_id.to_s
|
|
141
|
-
@client_secret = client_secret.to_s
|
|
152
|
+
@client_id = client_id&.to_s
|
|
153
|
+
@client_secret = client_secret&.to_s
|
|
154
|
+
@access_token = access_token&.to_s
|
|
142
155
|
|
|
143
156
|
super(
|
|
144
157
|
base_url: base_url,
|
|
@@ -165,5 +178,39 @@ module Spotted
|
|
|
165
178
|
@recommendations = Spotted::Resources::Recommendations.new(client: self)
|
|
166
179
|
@markets = Spotted::Resources::Markets.new(client: self)
|
|
167
180
|
end
|
|
181
|
+
|
|
182
|
+
# Generates the Spotify authorization URL for OAuth2 authorization code flow.
|
|
183
|
+
#
|
|
184
|
+
# @param redirect_uri [String] The URI to redirect to after authorization
|
|
185
|
+
# @param scope [String, Array<String>, nil] Space-delimited string or array of authorization scopes
|
|
186
|
+
# @param state [String, nil] Optional state parameter for CSRF protection
|
|
187
|
+
# @param show_dialog [Boolean] Whether to force the user to approve the app again
|
|
188
|
+
#
|
|
189
|
+
# @return [String] The authorization URL to redirect the user to
|
|
190
|
+
#
|
|
191
|
+
# @example Basic usage
|
|
192
|
+
# client = Spotted::Client.new(client_id: "...", client_secret: "...")
|
|
193
|
+
# url = client.authorization_url(redirect_uri: "http://localhost:3000/callback")
|
|
194
|
+
#
|
|
195
|
+
# @example With scopes and state
|
|
196
|
+
# url = client.authorization_url(
|
|
197
|
+
# redirect_uri: "http://localhost:3000/callback",
|
|
198
|
+
# scope: ["user-read-private", "user-read-email"],
|
|
199
|
+
# state: "random_state_string"
|
|
200
|
+
# )
|
|
201
|
+
def authorization_url(redirect_uri:, scope: nil, state: nil, show_dialog: false)
|
|
202
|
+
params = {
|
|
203
|
+
client_id: @client_id,
|
|
204
|
+
response_type: "code",
|
|
205
|
+
redirect_uri: redirect_uri
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
params[:scope] = scope.is_a?(Array) ? scope.join(" ") : scope if scope
|
|
209
|
+
params[:state] = state if state
|
|
210
|
+
params[:show_dialog] = "true" if show_dialog
|
|
211
|
+
|
|
212
|
+
query_string = URI.encode_www_form(params)
|
|
213
|
+
"https://accounts.spotify.com/authorize?#{query_string}"
|
|
214
|
+
end
|
|
168
215
|
end
|
|
169
216
|
end
|
data/lib/spotted/version.rb
CHANGED
data/rbi/spotted/client.rbi
CHANGED
|
@@ -10,12 +10,15 @@ module Spotted
|
|
|
10
10
|
|
|
11
11
|
DEFAULT_MAX_RETRY_DELAY = T.let(8.0, Float)
|
|
12
12
|
|
|
13
|
-
sig { returns(String) }
|
|
13
|
+
sig { returns(T.nilable(String)) }
|
|
14
14
|
attr_reader :client_id
|
|
15
15
|
|
|
16
|
-
sig { returns(String) }
|
|
16
|
+
sig { returns(T.nilable(String)) }
|
|
17
17
|
attr_reader :client_secret
|
|
18
18
|
|
|
19
|
+
sig { returns(T.nilable(String)) }
|
|
20
|
+
attr_reader :access_token
|
|
21
|
+
|
|
19
22
|
sig { returns(Spotted::Resources::Albums) }
|
|
20
23
|
attr_reader :albums
|
|
21
24
|
|
|
@@ -64,13 +67,23 @@ module Spotted
|
|
|
64
67
|
sig { returns(Spotted::Resources::Markets) }
|
|
65
68
|
attr_reader :markets
|
|
66
69
|
|
|
70
|
+
# @api private
|
|
71
|
+
sig { override.returns(T::Hash[String, String]) }
|
|
72
|
+
private def auth_headers
|
|
73
|
+
end
|
|
74
|
+
|
|
75
|
+
# @api private
|
|
76
|
+
sig { returns(T::Hash[String, String]) }
|
|
77
|
+
private def bearer_auth
|
|
78
|
+
end
|
|
79
|
+
|
|
67
80
|
# @api private
|
|
68
81
|
sig { returns(Spotted::Internal::OAuth2ClientCredentials) }
|
|
69
82
|
attr_reader :oauth_2_0_state
|
|
70
83
|
|
|
71
84
|
# @api private
|
|
72
|
-
sig {
|
|
73
|
-
private def
|
|
85
|
+
sig { returns(T::Hash[String, String]) }
|
|
86
|
+
private def oauth_2_0
|
|
74
87
|
end
|
|
75
88
|
|
|
76
89
|
# Creates and returns a new client for interacting with the API.
|
|
@@ -78,6 +91,7 @@ module Spotted
|
|
|
78
91
|
params(
|
|
79
92
|
client_id: T.nilable(String),
|
|
80
93
|
client_secret: T.nilable(String),
|
|
94
|
+
access_token: T.nilable(String),
|
|
81
95
|
base_url: T.nilable(String),
|
|
82
96
|
max_retries: Integer,
|
|
83
97
|
timeout: Float,
|
|
@@ -90,6 +104,8 @@ module Spotted
|
|
|
90
104
|
client_id: ENV["SPOTIFY_CLIENT_ID"],
|
|
91
105
|
# Defaults to `ENV["SPOTIFY_CLIENT_SECRET"]`
|
|
92
106
|
client_secret: ENV["SPOTIFY_CLIENT_SECRET"],
|
|
107
|
+
# Defaults to `ENV["SPOTIFY_ACCESS_TOKEN"]`
|
|
108
|
+
access_token: ENV["SPOTIFY_ACCESS_TOKEN"],
|
|
93
109
|
# Override the default base URL for the API, e.g.,
|
|
94
110
|
# `"https://api.example.com/v2/"`. Defaults to `ENV["SPOTTED_BASE_URL"]`
|
|
95
111
|
base_url: ENV["SPOTTED_BASE_URL"],
|
|
@@ -489,16 +489,21 @@ module Spotted
|
|
|
489
489
|
end
|
|
490
490
|
OrFloat = T.type_alias { Float }
|
|
491
491
|
|
|
492
|
+
# No result
|
|
492
493
|
MINUS_1 =
|
|
493
494
|
T.let(
|
|
494
495
|
-1,
|
|
495
496
|
Spotted::Models::AudioAnalysisRetrieveResponse::Section::Mode::TaggedFloat
|
|
496
497
|
)
|
|
498
|
+
|
|
499
|
+
# Minor
|
|
497
500
|
MODE_0 =
|
|
498
501
|
T.let(
|
|
499
502
|
0,
|
|
500
503
|
Spotted::Models::AudioAnalysisRetrieveResponse::Section::Mode::TaggedFloat
|
|
501
504
|
)
|
|
505
|
+
|
|
506
|
+
# Major
|
|
502
507
|
MODE_1 =
|
|
503
508
|
T.let(
|
|
504
509
|
1,
|
data/sig/spotted/client.rbs
CHANGED
|
@@ -8,9 +8,11 @@ module Spotted
|
|
|
8
8
|
|
|
9
9
|
DEFAULT_MAX_RETRY_DELAY: Float
|
|
10
10
|
|
|
11
|
-
attr_reader client_id: String
|
|
11
|
+
attr_reader client_id: String?
|
|
12
12
|
|
|
13
|
-
attr_reader client_secret: String
|
|
13
|
+
attr_reader client_secret: String?
|
|
14
|
+
|
|
15
|
+
attr_reader access_token: String?
|
|
14
16
|
|
|
15
17
|
attr_reader albums: Spotted::Resources::Albums
|
|
16
18
|
|
|
@@ -44,14 +46,19 @@ module Spotted
|
|
|
44
46
|
|
|
45
47
|
attr_reader markets: Spotted::Resources::Markets
|
|
46
48
|
|
|
49
|
+
private def auth_headers: -> ::Hash[String, String]
|
|
50
|
+
|
|
51
|
+
private def bearer_auth: -> ::Hash[String, String]
|
|
52
|
+
|
|
47
53
|
# @api private
|
|
48
54
|
attr_reader oauth_2_0_state: Spotted::Internal::OAuth2ClientCredentials
|
|
49
55
|
|
|
50
|
-
private def
|
|
56
|
+
private def oauth_2_0: -> ::Hash[String, String]
|
|
51
57
|
|
|
52
58
|
def initialize: (
|
|
53
59
|
?client_id: String?,
|
|
54
60
|
?client_secret: String?,
|
|
61
|
+
?access_token: String?,
|
|
55
62
|
?base_url: String?,
|
|
56
63
|
?max_retries: Integer,
|
|
57
64
|
?timeout: Float,
|
|
@@ -237,8 +237,13 @@ module Spotted
|
|
|
237
237
|
module Mode
|
|
238
238
|
extend Spotted::Internal::Type::Enum
|
|
239
239
|
|
|
240
|
+
# No result
|
|
240
241
|
MINUS_1: -1
|
|
242
|
+
|
|
243
|
+
# Minor
|
|
241
244
|
MODE_0: 0
|
|
245
|
+
|
|
246
|
+
# Major
|
|
242
247
|
MODE_1: 1
|
|
243
248
|
|
|
244
249
|
def self?.values: -> ::Array[Spotted::Models::AudioAnalysisRetrieveResponse::Section::mode]
|