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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 8531ff35eb3c2054c9d4d99b6e97c5e22848e3805dae010d4be01841e3d535a6
4
- data.tar.gz: f4775af30bd3ad47662b06ba8ebaefdef6b0d30378773e2ec520c54a4c672a36
3
+ metadata.gz: 1a6a776c3c8bbec1fba9afe39bf5d91da04789a313496873bd256b41564b0180
4
+ data.tar.gz: '09b9987a2dc0f5dbb7437701d4edc69d58abae3f11b2a3f9cb7ab2c330a88be2'
5
5
  SHA512:
6
- metadata.gz: 1892e985e4eff8f8f635e9438fc081832a65a6ac8717d73edaa17ee165219bdfcf29838e33b86ea6f06cf77489bedf418a90d06c2f114f1c5fc343e16615560a
7
- data.tar.gz: 2ff791f2c9c431305935f27345f1aa4e0001c59eaa132a7d4f1d839b3030ee8d8090aa4ee5be0b8aa75492ec113a243e996b6bd119b81340892e2c593c7cc106
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
- [![Gem Version](https://badge.fury.io/rb/spotify-client.svg)](https://rubygems.org/gems/spotify-client)
5
+ [![Test](https://github.com/icoretech/spotify-client/actions/workflows/test.yml/badge.svg?branch=main)](https://github.com/icoretech/spotify-client/actions/workflows/test.yml?query=branch%3Amain)
6
+ [![Gem Version](https://badge.fury.io/rb/spotify-client.svg)](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
- client.me_tracks
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.user(user_id)
54
- client.user_playlists(user_id) # user_id kept for backward compatibility; requests /v1/me/playlists
55
- client.user_playlist(user_id, playlist_id)
56
- client.user_playlist_tracks(user_id, playlist_id, params = {})
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
  ```
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Spotify
4
- VERSION = '1.0.2'
4
+ VERSION = '1.1.0'
5
5
  end
@@ -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
- run(:get, "/v1/playlists/#{playlist_id}", [200])
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
- run(:put, '/v1/me/library', [200, 204], JSON.dump(uris: uris), false)
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
- run(:put, '/v1/me/library', [200, 204], JSON.dump(uris: ["spotify:playlist:#{playlist_id}"]), false)
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.
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: spotify-client
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.2
4
+ version: 1.1.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Claudio Poli