spotify 12.5.3 → 12.6.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/.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
|