spotify 12.5.3 → 12.6.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.gitignore +2 -0
- data/.travis.yml +20 -5
- data/CHANGELOG.md +29 -1
- data/Gemfile +5 -0
- data/MIT-LICENSE +21 -0
- data/README.markdown +75 -50
- data/Rakefile +1 -1
- data/examples/example-audio_delivery_speed.rb +48 -0
- data/examples/{audio-stream_example.rb → example-audio_stream.rb} +14 -29
- data/examples/example-console.rb +9 -0
- data/examples/example-listing_playlists.rb +89 -0
- data/examples/example-loading_object.rb +25 -0
- data/examples/example-random_related_artists.rb +53 -0
- data/examples/support.rb +106 -0
- data/lib/spotify.rb +36 -55
- data/lib/spotify/api.rb +54 -26
- data/lib/spotify/api/album.rb +45 -2
- data/lib/spotify/api/album_browse.rb +81 -3
- data/lib/spotify/api/artist.rb +21 -2
- data/lib/spotify/api/artist_browse.rb +121 -3
- data/lib/spotify/api/error.rb +5 -1
- data/lib/spotify/api/image.rb +72 -6
- data/lib/spotify/api/inbox.rb +33 -4
- data/lib/spotify/api/link.rb +117 -4
- data/lib/spotify/api/miscellaneous.rb +12 -0
- data/lib/spotify/api/playlist.rb +321 -16
- data/lib/spotify/api/playlist_container.rb +168 -9
- data/lib/spotify/api/search.rb +156 -3
- data/lib/spotify/api/session.rb +390 -26
- data/lib/spotify/api/toplist_browse.rb +74 -3
- data/lib/spotify/api/track.rb +134 -4
- data/lib/spotify/api/user.rb +18 -2
- data/lib/spotify/api_helpers.rb +47 -0
- data/lib/spotify/data_converters.rb +7 -0
- data/lib/spotify/{types → data_converters}/best_effort_string.rb +1 -1
- data/lib/spotify/{types → data_converters}/byte_string.rb +0 -0
- data/lib/spotify/data_converters/country_code.rb +30 -0
- data/lib/spotify/{types → data_converters}/image_id.rb +1 -1
- data/lib/spotify/{type_safety.rb → data_converters/type_safety.rb} +0 -0
- data/lib/spotify/{types → data_converters}/utf8_string.rb +2 -2
- data/lib/spotify/{types → data_converters}/utf8_string_pointer.rb +2 -2
- data/lib/spotify/error.rb +180 -47
- data/lib/spotify/managed_pointer.rb +32 -12
- data/lib/spotify/monkey_patches/ffi_buffer.rb +11 -0
- data/lib/spotify/monkey_patches/ffi_enums.rb +4 -0
- data/lib/spotify/monkey_patches/ffi_pointer.rb +1 -0
- data/lib/spotify/structs.rb +4 -0
- data/lib/spotify/structs/session_callbacks.rb +97 -26
- data/lib/spotify/structs/session_config.rb +1 -1
- data/lib/spotify/structs/subscribers.rb +4 -3
- data/lib/spotify/types.rb +104 -5
- data/lib/spotify/{objects → types}/album.rb +0 -0
- data/lib/spotify/{objects → types}/album_browse.rb +0 -0
- data/lib/spotify/{objects → types}/artist.rb +0 -0
- data/lib/spotify/{objects → types}/artist_browse.rb +0 -0
- data/lib/spotify/{objects → types}/image.rb +0 -0
- data/lib/spotify/{objects → types}/inbox.rb +0 -0
- data/lib/spotify/{objects → types}/link.rb +0 -0
- data/lib/spotify/{objects → types}/playlist.rb +0 -0
- data/lib/spotify/{objects → types}/playlist_container.rb +0 -0
- data/lib/spotify/{objects → types}/search.rb +0 -0
- data/lib/spotify/{objects → types}/session.rb +0 -0
- data/lib/spotify/{objects → types}/toplist_browse.rb +0 -0
- data/lib/spotify/{objects → types}/track.rb +0 -0
- data/lib/spotify/{objects → types}/user.rb +0 -0
- data/lib/spotify/util.rb +38 -35
- data/lib/spotify/version.rb +1 -1
- data/spec/spec_helper.rb +24 -13
- data/spec/spotify/api/image_spec.rb +32 -0
- data/spec/spotify/api/inbox_spec.rb +34 -0
- data/spec/spotify/api/link_spec.rb +40 -0
- data/spec/spotify/api/playlist_spec.rb +99 -0
- data/spec/spotify/api/playlistcontainer_spec.rb +82 -0
- data/spec/spotify/api/session_spec.rb +97 -0
- data/spec/spotify/api/track_spec.rb +29 -0
- data/spec/spotify/api_error_spec.rb +55 -0
- data/spec/spotify/api_spec.rb +17 -11
- data/spec/spotify/{types → data_converters}/best_effort_string_spec.rb +4 -4
- data/spec/spotify/{types → data_converters}/byte_string_spec.rb +0 -0
- data/spec/spotify/data_converters/country_code_spec.rb +16 -0
- data/spec/spotify/{types → data_converters}/image_id_spec.rb +1 -1
- data/spec/spotify/{type_safety_spec.rb → data_converters/type_safety_spec.rb} +0 -0
- data/spec/spotify/{types → data_converters}/utf8_string_pointer_spec.rb +0 -0
- data/spec/spotify/{types → data_converters}/utf8_string_spec.rb +1 -1
- data/spec/spotify/{api/functions_spec.rb → functions_spec.rb} +2 -0
- data/spec/spotify/managed_pointer_spec.rb +13 -13
- data/spec/spotify/structs/subscribers_spec.rb +5 -3
- data/spec/spotify/{defines_spec.rb → types_spec.rb} +16 -3
- data/spec/spotify/util_spec.rb +24 -0
- data/spec/spotify_spec.rb +74 -0
- data/spec/support/spotify_util.rb +6 -2
- data/spec/support/spy_output.rb +16 -0
- data/spotify.gemspec +4 -2
- metadata +111 -71
- data/examples/README.md +0 -15
- data/examples/console_example.rb +0 -22
- data/examples/example_support.rb +0 -66
- data/examples/loading-object_example.rb +0 -43
- data/examples/logging-in_example.rb +0 -58
- data/lib/spotify/defines.rb +0 -109
- data/lib/spotify/objects.rb +0 -17
- data/spec/spotify/enums_spec.rb +0 -9
- data/spec/spotify/spotify_spec.rb +0 -69
data/lib/spotify/api/playlist.rb
CHANGED
@@ -1,39 +1,344 @@
|
|
1
1
|
module Spotify
|
2
2
|
class API
|
3
3
|
# @!group Playlist
|
4
|
+
|
5
|
+
# @param [Playlist] playlist
|
6
|
+
# @return [Boolean] true if playlist is loaded
|
7
|
+
# @method playlist_is_loaded(playlist)
|
4
8
|
attach_function :playlist_is_loaded, [ Playlist ], :bool
|
5
|
-
|
6
|
-
|
9
|
+
|
10
|
+
# Attach callbacks to the playlist, used for getting change notifications.
|
11
|
+
#
|
12
|
+
# @example
|
13
|
+
# callbacks = Spotify::PlaylistCallbacks.new({
|
14
|
+
# tracks_added: proc do |playlist, tracks_pointer, count, position|
|
15
|
+
# puts "#{count} tracks added at #{position}."
|
16
|
+
# end,
|
17
|
+
# playlist_renamed: proc { |playlist| puts "Playlist renamed!" },
|
18
|
+
# })
|
19
|
+
# Spotify.playlist_add_callbacks(playlist, callbacks, nil) # => ok
|
20
|
+
#
|
21
|
+
# @note it is *very* important that the callbacks are not garbage collected before they are called!
|
22
|
+
# @param [Playlist] playlist
|
23
|
+
# @param [PlaylistCallbacks] playlist_callbacks
|
24
|
+
# @param [FFI::Pointer] userdata
|
25
|
+
# @return [Symbol] error code
|
26
|
+
# @method playlist_add_callbacks(playlist, playlist_callbacks, userdata)
|
27
|
+
attach_function :playlist_add_callbacks, [ Playlist, PlaylistCallbacks.by_ref, :userdata ], APIError
|
28
|
+
|
29
|
+
# Remove playlist callbacks previously added with {#playlist_add_callbacks}.
|
30
|
+
#
|
31
|
+
# @see #playlist_add_callbacks
|
32
|
+
# @param [Playlist] playlist
|
33
|
+
# @param [PlaylistCallbacks] playlist_callbacks
|
34
|
+
# @param [FFI::Pointer] userdata
|
35
|
+
# @return [Symbol] error code
|
36
|
+
# @method playlist_remove_callbacks(playlist, playlist_callbacks, userdata)
|
37
|
+
attach_function :playlist_remove_callbacks, [ Playlist, PlaylistCallbacks.by_ref, :userdata ], APIError
|
38
|
+
|
39
|
+
# @see #playlist_track
|
40
|
+
# @note if playlist is not loaded, the function always return 0.
|
41
|
+
# @param [Playlist] playlist
|
42
|
+
# @return [Integer] number of tracks in the playlist
|
43
|
+
# @method playlist_num_tracks(playlist)
|
7
44
|
attach_function :playlist_num_tracks, [ Playlist ], :int
|
45
|
+
|
46
|
+
# @see #playlist_num_tracks
|
47
|
+
# @note if index is out of range, the function always return nil.
|
48
|
+
# @param [Playlist] playlist
|
49
|
+
# @param [Integer] index number between 0...{#playlist_num_tracks}
|
50
|
+
# @return [Track, nil] track at index
|
51
|
+
# @method playlist_track(playlist, index)
|
8
52
|
attach_function :playlist_track, [ Playlist, :int ], Track
|
53
|
+
|
54
|
+
# @see #playlist_num_tracks
|
55
|
+
# @note if index is out of range, the function always return -1.
|
56
|
+
# @param [Playlist] playlist
|
57
|
+
# @param [Integer] index number between 0...{#playlist_num_tracks}
|
58
|
+
# @return [Integer] time in seconds since unix epoch that track was added at index in the playlist
|
59
|
+
# @method playlist_track_create_time(playlist, index)
|
9
60
|
attach_function :playlist_track_create_time, [ Playlist, :int ], :int
|
61
|
+
|
62
|
+
# @see #playlist_num_tracks
|
63
|
+
# @note if index is out of range, the function always return nil.
|
64
|
+
# @param [Playlist] playlist
|
65
|
+
# @param [Integer] index number between 0...{#playlist_num_tracks}
|
66
|
+
# @return [User, nil] user that added the track at index in the playlist
|
67
|
+
# @method playlist_track_creator(playlist, index)
|
10
68
|
attach_function :playlist_track_creator, [ Playlist, :int ], User
|
69
|
+
|
70
|
+
# @see #playlist_num_tracks
|
71
|
+
# @see #playlist_track_set_seen
|
72
|
+
# @note if index is out of range, the function always return false.
|
73
|
+
# @param [Playlist] playlist
|
74
|
+
# @param [Integer] index number between 0...{#playlist_num_tracks}
|
75
|
+
# @return [Boolean] true if playlist has been marked as seen with {#playlist_track_set_seen}.
|
76
|
+
# @method playlist_track_seen(playlist, index)
|
11
77
|
attach_function :playlist_track_seen, [ Playlist, :int ], :bool
|
12
|
-
|
78
|
+
|
79
|
+
# Set `seen` flag on track. The flag can be retrieved by {#playlist_track_seen}.
|
80
|
+
#
|
81
|
+
# @see #playlist_num_tracks
|
82
|
+
# @see #playlist_track_seen
|
83
|
+
# @param [Playlist] playlist
|
84
|
+
# @param [Integer] index number between 0...{#playlist_num_tracks}
|
85
|
+
# @param [Boolean] seen
|
86
|
+
# @return [Symbol] error code
|
87
|
+
# @method playlist_track_set_seen(playlist, index, seen)
|
88
|
+
attach_function :playlist_track_set_seen, [ Playlist, :int, :bool ], APIError
|
89
|
+
|
90
|
+
# @see #playlist_num_tracks
|
91
|
+
# @note if index is out of range, the function always return nil.
|
92
|
+
# @param [Playlist] playlist
|
93
|
+
# @param [Integer] index number between 0...{#playlist_num_tracks}
|
94
|
+
# @return [String] message attached to a playlist item
|
95
|
+
# @method playlist_track_message(playlist, index)
|
13
96
|
attach_function :playlist_track_message, [ Playlist, :int ], UTF8String
|
97
|
+
|
98
|
+
# @see #playlist_is_loaded
|
99
|
+
# @note if playlist is not loaded, the function always return an empty string.
|
100
|
+
# @param [Playlist] playlist
|
101
|
+
# @return [String] name of the playlist
|
102
|
+
# @method playlist_name(playlist)
|
14
103
|
attach_function :playlist_name, [ Playlist ], UTF8String
|
15
|
-
|
104
|
+
|
105
|
+
# Rename the playlist.
|
106
|
+
#
|
107
|
+
# @see #playlist_is_loaded
|
108
|
+
# @note if playlist is not loaded, the function always return :permission_denied.
|
109
|
+
# @param [Playlist] playlist
|
110
|
+
# @param [String] new_name new name of the playlist
|
111
|
+
# @return [Symbol] error code
|
112
|
+
# @method playlist_rename(playlist, new_name)
|
113
|
+
attach_function :playlist_rename, [ Playlist, UTF8String ], APIError
|
114
|
+
|
115
|
+
# @param [Playlist] playlist
|
116
|
+
# @return [User] owner of the playlist
|
117
|
+
# @method playlist_owner(playlist)
|
16
118
|
attach_function :playlist_owner, [ Playlist ], User
|
119
|
+
|
120
|
+
# @see #playlist_is_loaded
|
121
|
+
# @see #playlist_set_collaborative
|
122
|
+
# @note if {#playlist_set_collaborative} was used, the final value will not be
|
123
|
+
# visible until after libspotify has negotiated with Spotify backend.
|
124
|
+
# @note if playlist is not loaded, the function always return false.
|
125
|
+
# @param [Playlist] playlist
|
126
|
+
# @return [Boolean] true if the playlist is collaborative, i.e. editable by others.
|
127
|
+
# @method playlist_is_collaborative(playlist)
|
17
128
|
attach_function :playlist_is_collaborative, [ Playlist ], :bool
|
18
|
-
|
19
|
-
|
129
|
+
|
130
|
+
# Set collaborative status on a playlist.
|
131
|
+
#
|
132
|
+
# @see #playlist_is_collaborative
|
133
|
+
# @note the function always return :ok.
|
134
|
+
# @param [Playlist] playlist
|
135
|
+
# @param [Boolean] collaborative
|
136
|
+
# @return [Symbol] error code
|
137
|
+
# @method playlist_set_collaborative(playlist, collaborative)
|
138
|
+
attach_function :playlist_set_collaborative, [ Playlist, :bool ], APIError
|
139
|
+
|
140
|
+
# Set autolinking state for a playlist.
|
141
|
+
#
|
142
|
+
# If a playlist is set to autolink, unplayable tracks will be made playable by
|
143
|
+
# linking them to an equivalent playable track when possible.
|
144
|
+
#
|
145
|
+
# @note the function always return :ok.
|
146
|
+
# @param [Playlist] playlist
|
147
|
+
# @param [Boolean] autolink
|
148
|
+
# @return [Symbol] error code
|
149
|
+
# @method playlist_set_autolink_tracks(playlist, autolink)
|
150
|
+
attach_function :playlist_set_autolink_tracks, [ Playlist, :bool ], APIError
|
151
|
+
|
152
|
+
# @see #playlist_is_loaded
|
153
|
+
# @note if the playlist is not loaded, the function always return nil.
|
154
|
+
# @param [Playlist] playlist
|
155
|
+
# @return [String, nil] playlist description, if available
|
156
|
+
# @method playlist_get_description(playlist)
|
20
157
|
attach_function :playlist_get_description, [ Playlist ], UTF8String
|
21
|
-
|
158
|
+
|
159
|
+
# Retrieve playlist image ID as a string.
|
160
|
+
#
|
161
|
+
# @example
|
162
|
+
# Spotify.playlist_get_image(playlist) # =>
|
163
|
+
#
|
164
|
+
# @see #playlist_is_loaded
|
165
|
+
# @see #image_create
|
166
|
+
# @note if the playlist is not loaded, the function always return nil.
|
167
|
+
# @param [Playlist] playlist
|
168
|
+
# @return [String, nil] image ID for playlist image, or nil if no image available.
|
169
|
+
# @method playlist_get_image(playlist)
|
170
|
+
attach_function :playlist_get_image, [ Playlist, :buffer_out ], :bool do |playlist|
|
171
|
+
with_buffer(Spotify::ImageID) do |image_id_buffer|
|
172
|
+
if sp_playlist_get_image(playlist, image_id_buffer)
|
173
|
+
ImageID.from_native(image_id_buffer, nil)
|
174
|
+
end
|
175
|
+
end
|
176
|
+
end
|
177
|
+
|
178
|
+
# @see #playlist_is_loaded
|
179
|
+
# @note if the playlist is not loaded, the function always return true.
|
180
|
+
# @param [Playlist] playlist
|
181
|
+
# @return [Boolean] true if the playlist has local changes that have not yet been acknowledged by Spotify backend
|
182
|
+
# @method playlist_has_pending_changes(playlist)
|
22
183
|
attach_function :playlist_has_pending_changes, [ Playlist ], :bool
|
23
|
-
|
24
|
-
|
25
|
-
|
184
|
+
|
185
|
+
# Add tracks to the playlist.
|
186
|
+
#
|
187
|
+
# @example single track
|
188
|
+
# Spotify.playlist_add_tracks(playlist, track, offset, session) # => :ok
|
189
|
+
#
|
190
|
+
# @example array of tracks
|
191
|
+
# Spotify.playlist_add_tracks(playlist, tracks, offset, session) # => :ok
|
192
|
+
#
|
193
|
+
# @see #playlist_is_loaded
|
194
|
+
# @note if the playlist is not loaded, the function always return an error.
|
195
|
+
#
|
196
|
+
# @param [Playlist] playlist
|
197
|
+
# @param [Array<Track>, Track] tracks
|
198
|
+
# @param [Integer] offset starting index to add tracks from
|
199
|
+
# @param [Session] session
|
200
|
+
# @return [Symbol] error code
|
201
|
+
# @method playlist_add_tracks(playlist, tracks, offset, session)
|
202
|
+
attach_function :playlist_add_tracks, [ Playlist, :array, :int, :int, Session ], APIError do |playlist, tracks, offset, session|
|
203
|
+
tracks = Array(tracks)
|
204
|
+
|
205
|
+
with_buffer(Spotify::Track, size: tracks.length) do |tracks_buffer|
|
206
|
+
tracks_buffer.write_array_of_pointer(tracks)
|
207
|
+
sp_playlist_add_tracks(playlist, tracks_buffer, tracks.length, offset, session)
|
208
|
+
end
|
209
|
+
end
|
210
|
+
|
211
|
+
# Remove tracks from the playlist at the given indices.
|
212
|
+
#
|
213
|
+
# @example single index
|
214
|
+
# Spotify.playlist_remove_tracks(playlist, 3) # => :ok
|
215
|
+
#
|
216
|
+
# @example array of indices
|
217
|
+
# Spotify.playlist_remove_tracks(playlist, [1, 3]) # => :ok
|
218
|
+
#
|
219
|
+
# @see #playlist_is_loaded
|
220
|
+
# @note if the playlist is not loaded, the function always return an error.
|
221
|
+
# @note any index in indices_pointer must exist at most once, i.e. [0,1,2] is valid, [0,0,1] is not.
|
222
|
+
# @param [Playlist] playlist
|
223
|
+
# @param [Array<Integer>, Integer] indices_pointer pointer to array of track indices
|
224
|
+
# @return [Symbol] error code
|
225
|
+
# @method playlist_remove_tracks(playlist, indices)
|
226
|
+
attach_function :playlist_remove_tracks, [ Playlist, :array, :int ], APIError do |playlist, indices|
|
227
|
+
indices = Array(indices)
|
228
|
+
|
229
|
+
with_buffer(:int, size: indices.length) do |indices_buffer|
|
230
|
+
indices_buffer.write_array_of_int(indices)
|
231
|
+
sp_playlist_remove_tracks(playlist, indices_buffer, indices.length)
|
232
|
+
end
|
233
|
+
end
|
234
|
+
|
235
|
+
# Move tracks at the given indices to position index and forward.
|
236
|
+
#
|
237
|
+
# @example
|
238
|
+
# Spotify.playlist_reorder_tracks(playlist, [1, 7], 0) # => :ok
|
239
|
+
#
|
240
|
+
# @see #playlist_is_loaded
|
241
|
+
# @note if the playlist is not loaded, the function always return an error.
|
242
|
+
# @note any index in indices_pointer must exist at most once, i.e. [0,1,2] is valid, [0,0,1] is not.
|
243
|
+
# @param [Playlist] playlist
|
244
|
+
# @param [Array<Integer>] indices_pointer pointer to array of track indices
|
245
|
+
# @param [Integer] index starting position of tracks to be placed at, number between 0..{#playlist_num_tracks}
|
246
|
+
# @return [Symbol] error code
|
247
|
+
# @method playlist_reorder_tracks(playlist, indices, index)
|
248
|
+
attach_function :playlist_reorder_tracks, [ Playlist, :array, :int, :int ], APIError do |playlist, indices, index|
|
249
|
+
indices = Array(indices)
|
250
|
+
|
251
|
+
with_buffer(:int, size: indices.length) do |indices_buffer|
|
252
|
+
indices_buffer.write_array_of_int(indices)
|
253
|
+
sp_playlist_reorder_tracks(playlist, indices_buffer, indices.length, index)
|
254
|
+
end
|
255
|
+
end
|
256
|
+
|
257
|
+
# @see #playlist_is_loaded
|
258
|
+
# @see #playlist_update_subscribers
|
259
|
+
# @note if the playlist is not loaded, the function always return 0.
|
260
|
+
# @note if {#playlist_update_subscribers} have not been called, the function always return 0.
|
261
|
+
# @param [Playlist] playlist
|
262
|
+
# @return [Integer] number of playlist subscribers
|
263
|
+
# @method playlist_num_subscribers(playlist)
|
26
264
|
attach_function :playlist_num_subscribers, [ Playlist ], :uint
|
265
|
+
|
266
|
+
# @example
|
267
|
+
# subscribers = Spotify.playlist_subscribers(playlist).to_a
|
268
|
+
# puts "Subscribers: ", subscribers.join(", ")
|
269
|
+
#
|
270
|
+
# @see #playlist_is_loaded
|
271
|
+
# @see #playlist_update_subscribers
|
272
|
+
# @see Subscribers
|
273
|
+
# @note if the playlist is not loaded, the function always return an empty structure.
|
274
|
+
# @note if {#playlist_update_subscribers} have not been called, the function always return an empty structure.
|
275
|
+
# @param [Playlist] playlist
|
276
|
+
# @return [Subscribers]
|
277
|
+
# @method playlist_subscribers(playlist)
|
27
278
|
attach_function :playlist_subscribers, [ Playlist ], Subscribers.auto_ptr
|
28
|
-
attach_function :playlist_subscribers_free, [ Subscribers.by_ref ],
|
29
|
-
|
279
|
+
attach_function :playlist_subscribers_free, [ Subscribers.by_ref ], APIError
|
280
|
+
|
281
|
+
# Request download of the subscribers list.
|
282
|
+
#
|
283
|
+
# @note the function updates subscribers asynchronously, see {PlaylistCallbacks#subscribers_changed} for callback.
|
284
|
+
# @param [Session] session
|
285
|
+
# @param [Playlist] playlist
|
286
|
+
# @return [Symbol] error code
|
287
|
+
# @method playlist_update_subscribers(session, playlist)
|
288
|
+
attach_function :playlist_update_subscribers, [ Session, Playlist ], APIError
|
289
|
+
|
290
|
+
# @see https://developer.spotify.com/docs/libspotify/12.1.51/group__playlist.html#ga967ad87f0db702513ecda82546f667c5
|
291
|
+
# @param [Session] session
|
292
|
+
# @param [Playlist] playlist
|
293
|
+
# @return [Boolean] true if playlist is loaded in memory, as opposed to only stored on disk.
|
294
|
+
# @method playlist_is_in_ram(session, playlist)
|
30
295
|
attach_function :playlist_is_in_ram, [ Session, Playlist ], :bool
|
31
|
-
|
296
|
+
|
297
|
+
# Set if playlist should be loaded into memory, as opposed to only read from on disk.
|
298
|
+
#
|
299
|
+
# @see https://developer.spotify.com/docs/libspotify/12.1.51/group__playlist.html#ga967ad87f0db702513ecda82546f667c5
|
300
|
+
# @param [Session] session
|
301
|
+
# @param [Playlist] playlist
|
302
|
+
# @param [Boolean] in_ram
|
303
|
+
# @return [Symbol] error code
|
304
|
+
# @method playlist_set_in_ram(session, playlist, in_ram)
|
305
|
+
attach_function :playlist_set_in_ram, [ Session, Playlist, :bool ], APIError
|
306
|
+
|
307
|
+
# Instantiate a Playlist from a Link.
|
308
|
+
#
|
309
|
+
# @param [Session] session
|
310
|
+
# @param [Link] link
|
311
|
+
# @return [Playlist, nil] playlist, or nil if link was not a valid playlist link
|
312
|
+
# @method playlist_create(session, link)
|
32
313
|
attach_function :playlist_create, [ Session, Link ], Playlist
|
314
|
+
|
315
|
+
# @see #playlist_is_loaded
|
316
|
+
# @see #playlist_set_offline_mode
|
317
|
+
# @note if the playlist is not loaded, the function always return :no.
|
318
|
+
# @param [Session] session
|
319
|
+
# @param [Playlist] playlist
|
320
|
+
# @return [Symbol] playlist offline status, one of :no, :yes, :downloading, or :waiting
|
321
|
+
# @method playlist_get_offline_status(session, playlist)
|
33
322
|
attach_function :playlist_get_offline_status, [ Session, Playlist ], :playlist_offline_status
|
323
|
+
|
324
|
+
# @note if the playlist is not loaded, the function always return 0.
|
325
|
+
# @note if the playlist is not marked for offline download, the function always return 0.
|
326
|
+
# @param [Session] session
|
327
|
+
# @param [Playlist] playlist
|
328
|
+
# @return [Integer] percentage of playlist downloaded, 0..100
|
329
|
+
# @method playlist_get_offline_download_completed(session, playlist)
|
34
330
|
attach_function :playlist_get_offline_download_completed, [ Session, Playlist ], :int
|
35
|
-
|
36
|
-
|
37
|
-
|
331
|
+
|
332
|
+
# Set if playlist should be marked for offline playback.
|
333
|
+
#
|
334
|
+
# @param [Session] session
|
335
|
+
# @param [Playlist] playlist
|
336
|
+
# @param [Boolean] offline true if playlist should be downloaded for offline usage
|
337
|
+
# @return [Symbol] error code
|
338
|
+
# @method playlist_set_offline_mode(session, playlist, offline)
|
339
|
+
attach_function :playlist_set_offline_mode, [ Session, Playlist, :bool ], APIError
|
340
|
+
|
341
|
+
attach_function :playlist_add_ref, [ Playlist ], APIError
|
342
|
+
attach_function :playlist_release, [ Playlist ], APIError
|
38
343
|
end
|
39
344
|
end
|
@@ -1,23 +1,182 @@
|
|
1
1
|
module Spotify
|
2
2
|
class API
|
3
3
|
# @!group PlaylistContainer
|
4
|
-
|
5
|
-
|
4
|
+
|
5
|
+
# Attach callbacks to the container, used for getting change notifications.
|
6
|
+
#
|
7
|
+
# @example
|
8
|
+
# callbacks = Spotify::PlaylistContainerCallbacks.new({
|
9
|
+
# container_loaded: proc { |playlist| puts "Container loaded!" },
|
10
|
+
# })
|
11
|
+
# Spotify.playlistcontainer_add_callbacks(container, callbacks, nil) # => :ok
|
12
|
+
#
|
13
|
+
# @note it is *very* important that the callbacks are not garbage collected before they are called!
|
14
|
+
# @param [PlaylistContainer] container
|
15
|
+
# @param [PlaylistContainerCallbacks] container_callbacks
|
16
|
+
# @param [FFI::Pointer] userdata
|
17
|
+
# @return [Symbol] error code
|
18
|
+
# @method playlistcontainer_add_callbacks(container, container_callbacks, userdata)
|
19
|
+
attach_function :playlistcontainer_add_callbacks, [ PlaylistContainer, PlaylistContainerCallbacks.by_ref, :userdata ], APIError
|
20
|
+
|
21
|
+
# Remove container callbacks previously added with {#playlistcontainer_add_callbacks}.
|
22
|
+
#
|
23
|
+
# @see #playlistcontainer_add_callbacks
|
24
|
+
# @param [PlaylistContainer] container
|
25
|
+
# @param [PlaylistCallbacks] container_callbacks
|
26
|
+
# @param [FFI::Pointer] userdata
|
27
|
+
# @return [Symbol] error code
|
28
|
+
# @method playlistcontainer_remove_callbacks(container, container_callbacks, userdata)
|
29
|
+
attach_function :playlistcontainer_remove_callbacks, [ PlaylistContainer, PlaylistContainerCallbacks.by_ref, :userdata ], APIError
|
30
|
+
|
31
|
+
# @see #playlistcontainer_is_loaded
|
32
|
+
# @see #playlistcontainer_playlist
|
33
|
+
# @note if the container is not loaded, the function will always return 0.
|
34
|
+
# @param [PlaylistContainer] container
|
35
|
+
# @return [Integer] number of playlists in container
|
36
|
+
# @method playlistcontainer_num_playlists(container)
|
6
37
|
attach_function :playlistcontainer_num_playlists, [ PlaylistContainer ], :int
|
38
|
+
|
39
|
+
# @see #playlistcontainer_num_playlists
|
40
|
+
# @note if index is out of range, the function always return nil.
|
41
|
+
# @param [PlaylistContainer] container
|
42
|
+
# @param [Integer] index number between 0...{#playlistcontainer_num_playlists}
|
43
|
+
# @return [Playlist, nil] playlist at index
|
44
|
+
# @method playlistcontainer_playlist(container)
|
7
45
|
attach_function :playlistcontainer_playlist, [ PlaylistContainer, :int ], Playlist
|
46
|
+
|
47
|
+
# @see #playlistcontainer_num_playlists
|
48
|
+
# @note if index is out of range, the function always return :playlist.
|
49
|
+
# @param [PlaylistContainer] container
|
50
|
+
# @param [Integer] index number between 0...{#playlistcontainer_num_playlists}
|
51
|
+
# @return [Symbol] playlist type of playlist at index, one of :playlist, :start_folder, :end_folder, :placeholder
|
52
|
+
# @method playlistcontainer_playlist_type(container, index)
|
8
53
|
attach_function :playlistcontainer_playlist_type, [ PlaylistContainer, :int ], :playlist_type
|
9
|
-
|
54
|
+
|
55
|
+
# Retrieve folder name of a folder in a container.
|
56
|
+
#
|
57
|
+
# @example
|
58
|
+
# Spotify.playlistcontainer_playlist_folder_name(container, index = 0) # => "Summer Playlists"
|
59
|
+
#
|
60
|
+
# @see #playlistcontainer_num_playlists
|
61
|
+
#
|
62
|
+
# @note the spotify client appear to constrain the name to 255 chars, so this function does too.
|
63
|
+
# @note if index is out of range, the function always return nil.
|
64
|
+
#
|
65
|
+
# @param [PlaylistContainer] container
|
66
|
+
# @param [Integer] index number between 0...{#playlistcontainer_num_playlists}
|
67
|
+
# @return [String, nil] name of the folder as a string, or nil if not a folder, or out of range
|
68
|
+
# @method playlistcontainer_playlist_folder_name(container, index)
|
69
|
+
attach_function :playlistcontainer_playlist_folder_name, [ PlaylistContainer, :int, :buffer_out, :int ], APIError do |container, index|
|
70
|
+
folder_name = with_string_buffer(255) do |folder_name_buffer, size|
|
71
|
+
sp_playlistcontainer_playlist_folder_name(container, index, folder_name_buffer, size)
|
72
|
+
end
|
73
|
+
|
74
|
+
folder_name unless folder_name.empty?
|
75
|
+
end
|
76
|
+
|
77
|
+
# @note if the index is out of range, the function always return 0.
|
78
|
+
# @param [PlaylistContainer] container
|
79
|
+
# @param [Integer] index number between 0...{#playlistcontainer_num_playlists}
|
80
|
+
# @return [Integer] folder id at index
|
81
|
+
# @method playlistcontainer_playlist_folder_id(container, index)
|
10
82
|
attach_function :playlistcontainer_playlist_folder_id, [ PlaylistContainer, :int ], :uint64
|
83
|
+
|
84
|
+
# Add a new playlist to the end of the container.
|
85
|
+
#
|
86
|
+
# @note the name must not constist of only spaces, and it must be shorter than 256 bytes.
|
87
|
+
# @param [PlaylistContainer] container
|
88
|
+
# @param [String] playlist_name name of the playlist
|
89
|
+
# @return [Playlist, nil] the new playlist, or nil if creation failed
|
90
|
+
# @method playlistcontainer_add_new_playlist(container, playlist_name)
|
11
91
|
attach_function :playlistcontainer_add_new_playlist, [ PlaylistContainer, UTF8String ], Playlist
|
92
|
+
|
93
|
+
# Add an existing playlist to the end of the container.
|
94
|
+
#
|
95
|
+
# @param [PlaylistContainer] container
|
96
|
+
# @param [Link] link link to a playlist
|
97
|
+
# @return [Playlist, nil] the playlist, or nil if the playlist already exists, or if the link was not a valid playlist link
|
98
|
+
# @method playlistcontainer_add_playlist(container, link)
|
12
99
|
attach_function :playlistcontainer_add_playlist, [ PlaylistContainer, Link ], Playlist
|
13
|
-
|
14
|
-
|
15
|
-
|
100
|
+
|
101
|
+
# Remove a playlist from a container.
|
102
|
+
#
|
103
|
+
# @note if you remove a folder marker, remove the other corresponding (start or stop) marker
|
104
|
+
# as well, or the playlist will be left in an inconsistent state.
|
105
|
+
#
|
106
|
+
# @note if the index is out of range, the function always return an error.
|
107
|
+
# @param [PlaylistContainer] container
|
108
|
+
# @param [Integer] index number between 0...{#playlistcontainer_num_playlists}
|
109
|
+
# @return [Symbol] error code
|
110
|
+
# @method playlistcontainer_remove_playlist(container, index)
|
111
|
+
attach_function :playlistcontainer_remove_playlist, [ PlaylistContainer, :int ], APIError
|
112
|
+
|
113
|
+
# Move a playlist to another position in the container.
|
114
|
+
#
|
115
|
+
# @note if the index is out of range, the function always return an error.
|
116
|
+
# @param [PlaylistContainer] container
|
117
|
+
# @param [Integer] index number between 0...{#playlistcontainer_num_playlists}
|
118
|
+
# @param [Integer] new_position
|
119
|
+
# @param [Boolean] dry_run do not move the playlist, only check if it is possible
|
120
|
+
# @return [Symbol] error code
|
121
|
+
# @method playlistcontainer_move_playlist(container, index, new_position, dry_run)
|
122
|
+
attach_function :playlistcontainer_move_playlist, [ PlaylistContainer, :int, :int, :bool ], APIError
|
123
|
+
|
124
|
+
# Create a new folder in the container.
|
125
|
+
#
|
126
|
+
# This creates a start_folder marker, and an end_folder marker right after it, at
|
127
|
+
# specified index.
|
128
|
+
#
|
129
|
+
# @note you cannot rename folders, if you want to do so you have to destroy the folder and recreate it
|
130
|
+
# @param [PlaylistContainer] container
|
131
|
+
# @param [Integer] index number between 0..{#playlistcontainer_num_playlists}
|
132
|
+
# @param [String] folder_name
|
133
|
+
# @method playlistcontainer_add_folder(container, index, folder_name)
|
134
|
+
attach_function :playlistcontainer_add_folder, [ PlaylistContainer, :int, UTF8String ], APIError
|
135
|
+
|
136
|
+
# @param [PlaylistContainer] container
|
137
|
+
# @return [User] owner of the container
|
138
|
+
# @method playlistcontainer_owner(container)
|
16
139
|
attach_function :playlistcontainer_owner, [ PlaylistContainer ], User
|
140
|
+
|
141
|
+
# @param [PlaylistContainer] container
|
142
|
+
# @return [Boolean] true if the container is loaded
|
143
|
+
# @method playlistcontainer_is_loaded(container)
|
17
144
|
attach_function :playlistcontainer_is_loaded, [ PlaylistContainer ], :bool
|
18
|
-
|
145
|
+
|
146
|
+
# Number of new tracks in playlist since {#playlistcontainer_clear_unseen_tracks} was called.
|
147
|
+
#
|
148
|
+
# @example number of unseen tracks in playlist
|
149
|
+
# Spotify.playlistcontainer_get_unseen_tracks(container, playlist) # => [#<Spotify::Track::Retaining address=0x103a36c10>…
|
150
|
+
#
|
151
|
+
# @note if the playlist is not in the container, this function always return an empty array.
|
152
|
+
#
|
153
|
+
# @param [PlaylistContainer] container
|
154
|
+
# @param [Playlist] playlist
|
155
|
+
# @return [Array<Track>] an array of unseen tracks
|
156
|
+
# @method playlistcontainer_get_unseen_tracks(container, playlist)
|
157
|
+
attach_function :playlistcontainer_get_unseen_tracks, [ PlaylistContainer, Playlist, :array, :int ], :int do |container, playlist|
|
158
|
+
count = sp_playlistcontainer_get_unseen_tracks(container, playlist, nil, 0)
|
159
|
+
tracks = with_buffer(Spotify::Track, size: count) do |tracks_buffer|
|
160
|
+
sp_playlistcontainer_get_unseen_tracks(container, playlist, tracks_buffer, count)
|
161
|
+
tracks_buffer.read_array_of_pointer(count).map do |pointer|
|
162
|
+
Spotify::Track.retaining_class.from_native(pointer, nil)
|
163
|
+
end
|
164
|
+
end
|
165
|
+
|
166
|
+
tracks || []
|
167
|
+
end
|
168
|
+
|
169
|
+
# Clear unseen tracks for a playlist on a container
|
170
|
+
#
|
171
|
+
# This will cause the next{#playlistcontainer_get_unseen_tracks} call to return 0.
|
172
|
+
#
|
173
|
+
# @param [PlaylistContainer] container
|
174
|
+
# @param [Playlist] playlist
|
175
|
+
# @return [Integer] 0 on success, and -1 on failure
|
176
|
+
# @method playlistcontainer_clear_unseen_tracks(container, playlist)
|
19
177
|
attach_function :playlistcontainer_clear_unseen_tracks, [ PlaylistContainer, Playlist ], :int
|
20
|
-
|
21
|
-
attach_function :
|
178
|
+
|
179
|
+
attach_function :playlistcontainer_add_ref, [ PlaylistContainer ], APIError
|
180
|
+
attach_function :playlistcontainer_release, [ PlaylistContainer ], APIError
|
22
181
|
end
|
23
182
|
end
|