spotify-client 1.0.2 → 1.1.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/README.md +61 -9
- data/lib/spotify/version.rb +1 -1
- data/lib/spotify_client.rb +139 -3
- 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: 1a6a776c3c8bbec1fba9afe39bf5d91da04789a313496873bd256b41564b0180
|
|
4
|
+
data.tar.gz: '09b9987a2dc0f5dbb7437701d4edc69d58abae3f11b2a3f9cb7ab2c330a88be2'
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: bd4aa7ea96354bdbb0d0dd5b9f9fc93840e67005419bc1ed8c5dada3405798db188c945a56b08e16872b3ab04829a87cdd163e987c72bb1b688c1ee1e77083fe
|
|
7
|
+
data.tar.gz: ae3a9d60e844e7677131c0c3425001d2495fd63c56f28b5d20d4bbc6d364734bb90804a6cd21a41f868460469895b17865de5ac79342d818fa3dc9f5c1f33489
|
data/README.md
CHANGED
|
@@ -2,7 +2,8 @@
|
|
|
2
2
|
|
|
3
3
|
Ruby client for the [Spotify Web API](https://developer.spotify.com/documentation/web-api).
|
|
4
4
|
|
|
5
|
-
[](https://github.com/icoretech/spotify-client/actions/workflows/test.yml?query=branch%3Amain)
|
|
6
|
+
[](https://badge.fury.io/rb/spotify-client)
|
|
6
7
|
|
|
7
8
|
## Installation
|
|
8
9
|
|
|
@@ -47,31 +48,82 @@ client = Spotify::Client.new(config)
|
|
|
47
48
|
## Public API
|
|
48
49
|
|
|
49
50
|
```ruby
|
|
51
|
+
# User
|
|
50
52
|
client.me
|
|
51
|
-
|
|
53
|
+
|
|
54
|
+
# Library
|
|
55
|
+
client.me_albums(params = {})
|
|
56
|
+
client.me_audiobooks(params = {})
|
|
57
|
+
client.me_episodes(params = {})
|
|
52
58
|
client.me_following
|
|
53
|
-
client.
|
|
54
|
-
client.
|
|
55
|
-
client.
|
|
56
|
-
client.
|
|
59
|
+
client.me_shows(params = {})
|
|
60
|
+
client.me_tracks
|
|
61
|
+
client.add_to_library(uris)
|
|
62
|
+
client.remove_from_library(uris)
|
|
63
|
+
client.user_playlists(user_id = nil) # backward-compatible signature; requests /v1/me/playlists
|
|
57
64
|
client.create_user_playlist(user_id, name, is_public = true)
|
|
65
|
+
client.change_playlist_details(user_id, playlist_id, attributes = {})
|
|
66
|
+
|
|
67
|
+
# Playlist
|
|
68
|
+
client.playlist(playlist_id)
|
|
69
|
+
client.playlist_cover_image(playlist_id)
|
|
70
|
+
client.upload_playlist_cover_image(playlist_id, image_base64_jpeg)
|
|
71
|
+
|
|
72
|
+
# Backward-compatible playlist helpers
|
|
73
|
+
client.user_playlist(user_id, playlist_id) # delegates to playlist(playlist_id)
|
|
74
|
+
client.user_playlist_tracks(user_id, playlist_id, params = {})
|
|
58
75
|
client.add_user_tracks_to_playlist(user_id, playlist_id, uris = [], position = nil)
|
|
59
76
|
client.remove_user_tracks_from_playlist(user_id, playlist_id, tracks)
|
|
60
77
|
client.replace_user_tracks_in_playlist(user_id, playlist_id, tracks)
|
|
61
78
|
client.truncate_user_playlist(user_id, playlist_id)
|
|
79
|
+
|
|
80
|
+
# Metadata
|
|
62
81
|
client.album(album_id)
|
|
63
82
|
client.album_tracks(album_id)
|
|
64
83
|
client.albums(album_ids)
|
|
65
|
-
client.track(track_id)
|
|
66
|
-
client.tracks(track_ids)
|
|
67
84
|
client.artist(artist_id)
|
|
68
85
|
client.artists(artist_ids)
|
|
69
86
|
client.artist_albums(artist_id)
|
|
70
|
-
client.search(entity, term, options = {})
|
|
71
87
|
client.artist_top_tracks(artist_id, country_id)
|
|
88
|
+
client.audiobook(audiobook_id, params = {})
|
|
89
|
+
client.audiobook_chapters(audiobook_id, params = {})
|
|
90
|
+
client.chapter(chapter_id, params = {})
|
|
91
|
+
client.episode(episode_id, params = {})
|
|
92
|
+
client.show(show_id, params = {})
|
|
93
|
+
client.show_episodes(show_id, params = {})
|
|
94
|
+
client.track(track_id)
|
|
95
|
+
client.tracks(track_ids)
|
|
96
|
+
|
|
97
|
+
# Personalisation
|
|
98
|
+
client.me_top(type, params = {}) # type: "artists" or "tracks"
|
|
99
|
+
|
|
100
|
+
# Player
|
|
101
|
+
client.currently_playing(params = {})
|
|
102
|
+
client.recently_played(params = {})
|
|
103
|
+
client.playback_state(params = {})
|
|
104
|
+
client.available_devices
|
|
105
|
+
client.transfer_playback(device_ids, play = nil)
|
|
106
|
+
client.start_or_resume_playback(payload = {})
|
|
107
|
+
client.pause_playback(params = {})
|
|
108
|
+
client.skip_to_next(params = {})
|
|
109
|
+
client.skip_to_previous(params = {})
|
|
110
|
+
client.seek_to_position(position_ms, params = {})
|
|
111
|
+
client.set_repeat_mode(state, params = {})
|
|
112
|
+
client.set_playback_volume(volume_percent, params = {})
|
|
113
|
+
client.set_shuffle(state, params = {})
|
|
114
|
+
client.playback_queue(params = {})
|
|
115
|
+
client.add_to_playback_queue(uri, params = {})
|
|
116
|
+
|
|
117
|
+
# Search
|
|
118
|
+
client.search(entity, term, options = {}) # entity: :artist, :album, :track
|
|
119
|
+
|
|
120
|
+
# Legacy helpers kept for compatibility
|
|
121
|
+
client.user(user_id)
|
|
72
122
|
client.related_artists(artist_id)
|
|
73
123
|
client.follow(type, ids)
|
|
74
124
|
client.follow_playlist(user_id, playlist_id, is_public = true)
|
|
125
|
+
|
|
126
|
+
# Generic helpers for forward compatibility
|
|
75
127
|
client.request(:get, '/v1/me') # generic helper for newer endpoints
|
|
76
128
|
client.request!(:post, '/v1/some-endpoint', [201], payload, false)
|
|
77
129
|
```
|
data/lib/spotify/version.rb
CHANGED
data/lib/spotify_client.rb
CHANGED
|
@@ -44,6 +44,22 @@ module Spotify
|
|
|
44
44
|
run(:get, '/v1/me/tracks', [200])
|
|
45
45
|
end
|
|
46
46
|
|
|
47
|
+
def me_albums(params = {})
|
|
48
|
+
run(:get, '/v1/me/albums', [200], params)
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
def me_audiobooks(params = {})
|
|
52
|
+
run(:get, '/v1/me/audiobooks', [200], params)
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
def me_episodes(params = {})
|
|
56
|
+
run(:get, '/v1/me/episodes', [200], params)
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
def me_shows(params = {})
|
|
60
|
+
run(:get, '/v1/me/shows', [200], params)
|
|
61
|
+
end
|
|
62
|
+
|
|
47
63
|
# params:
|
|
48
64
|
# - type: Required, The ID type, currently only 'artist' is supported
|
|
49
65
|
# - limit: Optional. The maximum number of items to return. Default: 20. Minimum: 1. Maximum: 50.
|
|
@@ -66,7 +82,7 @@ module Spotify
|
|
|
66
82
|
end
|
|
67
83
|
|
|
68
84
|
def user_playlist(_user_id, playlist_id)
|
|
69
|
-
|
|
85
|
+
playlist(playlist_id)
|
|
70
86
|
end
|
|
71
87
|
|
|
72
88
|
def user_playlist_tracks(_user_id, playlist_id, params = {})
|
|
@@ -92,6 +108,10 @@ module Spotify
|
|
|
92
108
|
run(:post, '/v1/me/playlists', [201], JSON.dump(name: name, public: is_public), false)
|
|
93
109
|
end
|
|
94
110
|
|
|
111
|
+
def change_playlist_details(_user_id, playlist_id, attributes = {})
|
|
112
|
+
run(:put, "/v1/playlists/#{playlist_id}", [200, 204], JSON.dump(attributes), false)
|
|
113
|
+
end
|
|
114
|
+
|
|
95
115
|
# Add an Array of track uris to an existing playlist.
|
|
96
116
|
#
|
|
97
117
|
# Adding tracks to a user's public playlist requires authorization of the playlist-modify-public scope;
|
|
@@ -131,6 +151,18 @@ module Spotify
|
|
|
131
151
|
replace_user_tracks_in_playlist(user_id, playlist_id, [])
|
|
132
152
|
end
|
|
133
153
|
|
|
154
|
+
def playlist(playlist_id)
|
|
155
|
+
run(:get, "/v1/playlists/#{playlist_id}", [200])
|
|
156
|
+
end
|
|
157
|
+
|
|
158
|
+
def playlist_cover_image(playlist_id)
|
|
159
|
+
run(:get, "/v1/playlists/#{playlist_id}/images", [200], {})
|
|
160
|
+
end
|
|
161
|
+
|
|
162
|
+
def upload_playlist_cover_image(playlist_id, image_base64_jpeg)
|
|
163
|
+
run(:put, "/v1/playlists/#{playlist_id}/images", [200, 202, 204], image_base64_jpeg.to_s, false)
|
|
164
|
+
end
|
|
165
|
+
|
|
134
166
|
def album(album_id)
|
|
135
167
|
run(:get, "/v1/albums/#{album_id}", [200])
|
|
136
168
|
end
|
|
@@ -163,6 +195,30 @@ module Spotify
|
|
|
163
195
|
run(:get, "/v1/artists/#{artist_id}/albums", [200])
|
|
164
196
|
end
|
|
165
197
|
|
|
198
|
+
def audiobook(audiobook_id, params = {})
|
|
199
|
+
run(:get, "/v1/audiobooks/#{audiobook_id}", [200], params)
|
|
200
|
+
end
|
|
201
|
+
|
|
202
|
+
def audiobook_chapters(audiobook_id, params = {})
|
|
203
|
+
run(:get, "/v1/audiobooks/#{audiobook_id}/chapters", [200], params)
|
|
204
|
+
end
|
|
205
|
+
|
|
206
|
+
def chapter(chapter_id, params = {})
|
|
207
|
+
run(:get, "/v1/chapters/#{chapter_id}", [200], params)
|
|
208
|
+
end
|
|
209
|
+
|
|
210
|
+
def episode(episode_id, params = {})
|
|
211
|
+
run(:get, "/v1/episodes/#{episode_id}", [200], params)
|
|
212
|
+
end
|
|
213
|
+
|
|
214
|
+
def show(show_id, params = {})
|
|
215
|
+
run(:get, "/v1/shows/#{show_id}", [200], params)
|
|
216
|
+
end
|
|
217
|
+
|
|
218
|
+
def show_episodes(show_id, params = {})
|
|
219
|
+
run(:get, "/v1/shows/#{show_id}/episodes", [200], params)
|
|
220
|
+
end
|
|
221
|
+
|
|
166
222
|
def search(entity, term, options = {})
|
|
167
223
|
unless %i[artist album track].include?(entity.to_sym)
|
|
168
224
|
raise(ImplementationError, "entity needs to be either artist, album or track, got: #{entity}")
|
|
@@ -190,6 +246,86 @@ module Spotify
|
|
|
190
246
|
run(:get, "/v1/artists/#{artist_id}/related-artists", [200])
|
|
191
247
|
end
|
|
192
248
|
|
|
249
|
+
def me_top(type, params = {})
|
|
250
|
+
valid_types = %w[artists tracks]
|
|
251
|
+
normalized_type = type.to_s
|
|
252
|
+
unless valid_types.include?(normalized_type)
|
|
253
|
+
raise(ImplementationError, "type needs to be one of #{valid_types.join(', ')}, got: #{type}")
|
|
254
|
+
end
|
|
255
|
+
|
|
256
|
+
run(:get, "/v1/me/top/#{normalized_type}", [200], params)
|
|
257
|
+
end
|
|
258
|
+
|
|
259
|
+
def currently_playing(params = {})
|
|
260
|
+
run(:get, '/v1/me/player/currently-playing', [200], params)
|
|
261
|
+
end
|
|
262
|
+
|
|
263
|
+
def recently_played(params = {})
|
|
264
|
+
run(:get, '/v1/me/player/recently-played', [200], params)
|
|
265
|
+
end
|
|
266
|
+
|
|
267
|
+
def playback_state(params = {})
|
|
268
|
+
run(:get, '/v1/me/player', [200], params)
|
|
269
|
+
end
|
|
270
|
+
|
|
271
|
+
def available_devices
|
|
272
|
+
run(:get, '/v1/me/player/devices', [200], {})
|
|
273
|
+
end
|
|
274
|
+
|
|
275
|
+
def transfer_playback(device_ids, play = nil)
|
|
276
|
+
body = { device_ids: Array(device_ids) }
|
|
277
|
+
body[:play] = play unless play.nil?
|
|
278
|
+
run(:put, '/v1/me/player', [200, 204], JSON.dump(body), false)
|
|
279
|
+
end
|
|
280
|
+
|
|
281
|
+
def start_or_resume_playback(payload = {})
|
|
282
|
+
run(:put, '/v1/me/player/play', [200, 204], JSON.dump(payload), false)
|
|
283
|
+
end
|
|
284
|
+
|
|
285
|
+
def pause_playback(params = {})
|
|
286
|
+
run(:put, '/v1/me/player/pause', [200, 204], params, false)
|
|
287
|
+
end
|
|
288
|
+
|
|
289
|
+
def skip_to_next(params = {})
|
|
290
|
+
run(:post, '/v1/me/player/next', [200, 204], params, false)
|
|
291
|
+
end
|
|
292
|
+
|
|
293
|
+
def skip_to_previous(params = {})
|
|
294
|
+
run(:post, '/v1/me/player/previous', [200, 204], params, false)
|
|
295
|
+
end
|
|
296
|
+
|
|
297
|
+
def seek_to_position(position_ms, params = {})
|
|
298
|
+
run(:put, '/v1/me/player/seek', [200, 204], params.merge(position_ms: position_ms), false)
|
|
299
|
+
end
|
|
300
|
+
|
|
301
|
+
def set_repeat_mode(state, params = {})
|
|
302
|
+
run(:put, '/v1/me/player/repeat', [200, 204], params.merge(state: state), false)
|
|
303
|
+
end
|
|
304
|
+
|
|
305
|
+
def set_playback_volume(volume_percent, params = {})
|
|
306
|
+
run(:put, '/v1/me/player/volume', [200, 204], params.merge(volume_percent: volume_percent), false)
|
|
307
|
+
end
|
|
308
|
+
|
|
309
|
+
def set_shuffle(state, params = {})
|
|
310
|
+
run(:put, '/v1/me/player/shuffle', [200, 204], params.merge(state: state), false)
|
|
311
|
+
end
|
|
312
|
+
|
|
313
|
+
def playback_queue(params = {})
|
|
314
|
+
run(:get, '/v1/me/player/queue', [200], params)
|
|
315
|
+
end
|
|
316
|
+
|
|
317
|
+
def add_to_playback_queue(uri, params = {})
|
|
318
|
+
run(:post, '/v1/me/player/queue', [200, 204], params.merge(uri: uri), false)
|
|
319
|
+
end
|
|
320
|
+
|
|
321
|
+
def add_to_library(uris)
|
|
322
|
+
run(:put, '/v1/me/library', [200, 204], JSON.dump(uris: Array(uris)), false)
|
|
323
|
+
end
|
|
324
|
+
|
|
325
|
+
def remove_from_library(uris)
|
|
326
|
+
run(:delete, '/v1/me/library', [200, 204], JSON.dump(uris: Array(uris)), false)
|
|
327
|
+
end
|
|
328
|
+
|
|
193
329
|
# Follow artists or users
|
|
194
330
|
#
|
|
195
331
|
# client.follow('artist', ['0BvkDsjIUla7X0k6CSWh1I'])
|
|
@@ -203,7 +339,7 @@ module Spotify
|
|
|
203
339
|
|
|
204
340
|
"spotify:#{entity_type}:#{raw}"
|
|
205
341
|
end
|
|
206
|
-
|
|
342
|
+
add_to_library(uris)
|
|
207
343
|
end
|
|
208
344
|
|
|
209
345
|
# Follow a playlist
|
|
@@ -211,7 +347,7 @@ module Spotify
|
|
|
211
347
|
# client.follow_playlist('lukebryan', '0obRj9nNySESpFelMCLSya')
|
|
212
348
|
def follow_playlist(_user_id, playlist_id, is_public = true)
|
|
213
349
|
_is_public = is_public # kept for backward-compatible signature
|
|
214
|
-
|
|
350
|
+
add_to_library(["spotify:playlist:#{playlist_id}"])
|
|
215
351
|
end
|
|
216
352
|
|
|
217
353
|
# Generic API helper for forward compatibility with newly added endpoints.
|