spotify 12.0.0 → 12.0.1

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.
@@ -0,0 +1,165 @@
1
+ # This file contains functions that automatically raise when
2
+ # their libspotify function returns a non-ok error.
3
+
4
+ module Spotify
5
+ # Raised on error-wrapped functions when the result is non-ok.
6
+ class Error < StandardError
7
+ class << self
8
+ # Explain a Spotify error with a descriptive message.
9
+ #
10
+ # @param [Symbol, Integer] error
11
+ # @return [String] a decriptive string of the error
12
+ def explain(error)
13
+ error, symbol = disambiguate(error)
14
+
15
+ message = []
16
+ message << "[#{symbol.to_s.upcase}]"
17
+ message << Spotify.error_message(error)
18
+ message << "(#{error})"
19
+
20
+ message.join(' ')
21
+ end
22
+
23
+ # Given a number or a symbol, find both the symbol and the error
24
+ # number it represents.
25
+ #
26
+ # @example given an integer
27
+ # Spotify::Error.disambiguate(0) # => [0, :ok]
28
+ #
29
+ # @example given a symbol
30
+ # Spotify::Error.disambiguate(:ok) # => [0, :ok]
31
+ #
32
+ # @example given bogus
33
+ # Spotify::Error.disambiguate(:bogus) # => [-1, nil]
34
+ #
35
+ # @param [Symbol, Fixnum] error
36
+ # @return [[Fixnum, Symbol]] (error code, error symbol)
37
+ def disambiguate(error)
38
+ @enum ||= Spotify.enum_type(:error)
39
+
40
+ if error.is_a? Symbol
41
+ error = @enum[symbol = error]
42
+ else
43
+ symbol = @enum[error]
44
+ end
45
+
46
+ if error.nil? || symbol.nil?
47
+ [-1, nil]
48
+ else
49
+ [error, symbol]
50
+ end
51
+ end
52
+ end
53
+ end
54
+
55
+ # Wraps the function `function` so that it raises an error if
56
+ # the return error is not :ok.
57
+ #
58
+ # @note This method is removed at the bottom of this file.
59
+ #
60
+ # @param [#to_s] function
61
+ # @raise [NoMethodError] if `function` is not defined
62
+ def self.wrap_function(function)
63
+ method(function) # make sure it exists
64
+ define_singleton_method("#{function}!") do |*args, &block|
65
+ error = public_send(function, *args, &block)
66
+ raise Error, Error.explain(error) unless error == :ok
67
+ end
68
+ end
69
+
70
+ wrap_function :session_create
71
+ wrap_function :session_release
72
+ wrap_function :session_process_events
73
+ wrap_function :session_login
74
+ wrap_function :session_relogin
75
+ wrap_function :session_forget_me
76
+ wrap_function :session_logout
77
+ wrap_function :session_set_cache_size
78
+ wrap_function :session_player_load
79
+ wrap_function :session_player_seek
80
+ wrap_function :session_player_play
81
+ wrap_function :session_player_unload
82
+ wrap_function :session_player_prefetch
83
+ wrap_function :session_preferred_bitrate
84
+ wrap_function :session_set_connection_type
85
+ wrap_function :session_set_connection_rules
86
+ wrap_function :session_preferred_offline_bitrate
87
+ wrap_function :session_set_volume_normalization
88
+ wrap_function :session_flush_caches
89
+ wrap_function :session_set_private_session
90
+ wrap_function :session_set_scrobbling
91
+ wrap_function :session_is_scrobbling
92
+ wrap_function :session_is_scrobbling_possible
93
+ wrap_function :session_set_social_credentials
94
+
95
+ wrap_function :image_add_load_callback
96
+ wrap_function :image_remove_load_callback
97
+ wrap_function :image_error
98
+ wrap_function :image_add_ref
99
+ wrap_function :image_release
100
+
101
+ wrap_function :link_add_ref
102
+ wrap_function :link_release
103
+
104
+ wrap_function :track_error
105
+ wrap_function :track_set_starred
106
+ wrap_function :track_add_ref
107
+ wrap_function :track_release
108
+
109
+ wrap_function :album_add_ref
110
+ wrap_function :album_release
111
+
112
+ wrap_function :albumbrowse_error
113
+ wrap_function :albumbrowse_add_ref
114
+ wrap_function :albumbrowse_release
115
+
116
+ wrap_function :artist_add_ref
117
+ wrap_function :artist_release
118
+
119
+ wrap_function :artistbrowse_error
120
+ wrap_function :artistbrowse_add_ref
121
+ wrap_function :artistbrowse_release
122
+
123
+ wrap_function :search_error
124
+ wrap_function :search_add_ref
125
+ wrap_function :search_release
126
+
127
+ wrap_function :playlist_add_callbacks
128
+ wrap_function :playlist_remove_callbacks
129
+ wrap_function :playlist_track_set_seen
130
+ wrap_function :playlist_rename
131
+ wrap_function :playlist_set_collaborative
132
+ wrap_function :playlist_set_autolink_tracks
133
+ wrap_function :playlist_add_tracks
134
+ wrap_function :playlist_remove_tracks
135
+ wrap_function :playlist_reorder_tracks
136
+ wrap_function :playlist_subscribers_free
137
+ wrap_function :playlist_update_subscribers
138
+ wrap_function :playlist_set_in_ram
139
+ wrap_function :playlist_set_offline_mode
140
+ wrap_function :playlist_add_ref
141
+ wrap_function :playlist_release
142
+
143
+ wrap_function :playlistcontainer_add_callbacks
144
+ wrap_function :playlistcontainer_remove_callbacks
145
+ wrap_function :playlistcontainer_playlist_folder_name
146
+ wrap_function :playlistcontainer_remove_playlist
147
+ wrap_function :playlistcontainer_move_playlist
148
+ wrap_function :playlistcontainer_add_folder
149
+ wrap_function :playlistcontainer_add_ref
150
+ wrap_function :playlistcontainer_release
151
+
152
+ wrap_function :user_add_ref
153
+ wrap_function :user_release
154
+
155
+ wrap_function :toplistbrowse_error
156
+ wrap_function :toplistbrowse_add_ref
157
+ wrap_function :toplistbrowse_release
158
+
159
+ wrap_function :inbox_error
160
+ wrap_function :inbox_add_ref
161
+ wrap_function :inbox_release
162
+
163
+ # Clean up
164
+ class << self; undef :wrap_function; end
165
+ end
@@ -0,0 +1,730 @@
1
+ # This file contains the *actual* FFI bindings to the libspotify functions.
2
+
3
+ # FFI wrapper around libspotify.
4
+ #
5
+ # See official documentation for more detailed documentation about
6
+ # functions and their behavior.
7
+ #
8
+ # @see http://developer.spotify.com/en/libspotify/docs/
9
+ module Spotify
10
+ extend FFI::Library
11
+
12
+ begin
13
+ ffi_lib ['libspotify', '/Library/Frameworks/libspotify.framework/libspotify']
14
+ rescue LoadError => e
15
+ puts "Failed to load the `libspotify` library. Please make sure you have it
16
+ installed, either globally on your system, in your LD_LIBRARY_PATH, or in
17
+ your current working directory (#{Dir.pwd}).
18
+
19
+ For installation instructions, please see:
20
+ https://github.com/Burgestrand/Hallon/wiki/How-to-install-libspotify".gsub(/^ */, '')
21
+ puts
22
+ raise
23
+ end
24
+
25
+ # Fetches the associated value of an enum from a given symbol.
26
+ #
27
+ # @example retrieving a value
28
+ # Spotify.enum_value!(:ok, "error value") # => 0
29
+ #
30
+ # @example failing to retrieve a value
31
+ # Spotify.enum_value!(:moo, "connection rule") # => ArgumentError, invalid connection rule: :moo
32
+ #
33
+ # @param [Symbol] symbol
34
+ # @param [#to_s] type used as error message when the symbol does not resolve
35
+ # @raise ArgumentError on failure
36
+ def self.enum_value!(symbol, type)
37
+ enum_value(symbol) or raise ArgumentError, "invalid #{type}: #{symbol}"
38
+ end
39
+
40
+ # Override FFI::Library#attach_function to always add the `:blocking` option.
41
+ #
42
+ # The reason for this is that which libspotify functions may call callbacks
43
+ # is unspecified. And really… I don’t know of any drawbacks with this method.
44
+ def self.attach_function(*arguments, &block)
45
+ options = arguments.pop if arguments.last.is_a?(Hash)
46
+ options ||= {}
47
+ options = { :blocking => true }.merge(options)
48
+ arguments << options
49
+ super(*arguments, &block)
50
+ end
51
+
52
+ # libspotify API version
53
+ # @return [Fixnum]
54
+ API_VERSION = VERSION.split('.').first.to_i
55
+
56
+ # Aliases to Spotify types
57
+ typedef :pointer, :frames
58
+ typedef :pointer, :session
59
+ typedef :pointer, :track
60
+ typedef :pointer, :user
61
+ typedef :pointer, :playlistcontainer
62
+ typedef :pointer, :playlist
63
+ typedef :pointer, :link
64
+ typedef :pointer, :album
65
+ typedef :pointer, :artist
66
+ typedef :pointer, :search
67
+ typedef :pointer, :image
68
+ typedef :pointer, :albumbrowse
69
+ typedef :pointer, :artistbrowse
70
+ typedef :pointer, :toplistbrowse
71
+ typedef :pointer, :inbox
72
+
73
+ typedef :pointer, :userdata
74
+ typedef :pointer, :array
75
+
76
+ typedef :pointer, :string_pointer
77
+
78
+ typedef UTF8String, :utf8_string
79
+ typedef ImageID, :image_id
80
+
81
+ #
82
+ # Error
83
+ #
84
+ # @see http://developer.spotify.com/en/libspotify/docs/group__error.html
85
+
86
+ #
87
+ enum :error, [:ok, 0,
88
+ :bad_api_version, :api_initialization_failed, :track_not_playable,
89
+
90
+ :bad_application_key, 5,
91
+ :bad_username_or_password, :user_banned,
92
+ :unable_to_contact_server, :client_too_old, :other_permanent,
93
+ :bad_user_agent, :missing_callback, :invalid_indata,
94
+ :index_out_of_range, :user_needs_premium, :other_transient,
95
+ :is_loading, :no_stream_available, :permission_denied,
96
+ :inbox_is_full, :no_cache, :no_such_user, :no_credentials,
97
+ :network_disabled, :invalid_device_id, :cant_open_trace_file,
98
+ :application_banned,
99
+
100
+ :offline_too_many_tracks, 31,
101
+ :offline_disk_cache, :offline_expired, :offline_not_allowed,
102
+ :offline_license_lost, :offline_license_error,
103
+
104
+ :lastfm_auth_error, 39,
105
+ :invalid_argument, :system_failure]
106
+
107
+ # @macro [attach] attach_function
108
+ #
109
+ # Calls +$2+. See source for actual parameters.
110
+ #
111
+ # @method $1($3)
112
+ # @return [$4]
113
+ attach_function :error_message, :sp_error_message, [ :error ], :utf8_string
114
+
115
+ #
116
+ # Miscellaneous
117
+ #
118
+ # These don’t fit anywhere else :(
119
+ attach_function :build_id, :sp_build_id, [], :utf8_string
120
+
121
+ #
122
+ # Audio
123
+ #
124
+ # @see http://developer.spotify.com/en/libspotify/docs/group__session.html
125
+
126
+ #
127
+ enum :sampletype, [:int16] # int16_native_endian
128
+ enum :bitrate, %w(160k 320k 96k).map(&:to_sym)
129
+
130
+ # FFI::Struct for Audio Format.
131
+ #
132
+ # @attr [:sampletype] sample_type
133
+ # @attr [Fixnum] sample_rate
134
+ # @attr [Fixnum] channels
135
+ class AudioFormat < FFI::Struct
136
+ layout :sample_type, :sampletype,
137
+ :sample_rate, :int,
138
+ :channels, :int
139
+ end
140
+
141
+ # FFI::Struct for Audio Buffer Stats.
142
+ #
143
+ # @attr [Fixnum] samples
144
+ # @attr [Fixnum] stutter
145
+ class AudioBufferStats < FFI::Struct
146
+ layout :samples, :int,
147
+ :stutter, :int
148
+ end
149
+
150
+ #
151
+ # Session
152
+ #
153
+ # @see http://developer.spotify.com/en/libspotify/docs/group__session.html
154
+
155
+ # FFI::Struct for Session callbacks.
156
+ #
157
+ # @attr [callback(:session, :error):void] logged_in
158
+ # @attr [callback(:session):void] logged_out
159
+ # @attr [callback(:session):void] metadata_updated
160
+ # @attr [callback(:session, :error):void] connection_error
161
+ # @attr [callback(:session, :utf8_string):void] message_to_user
162
+ # @attr [callback(:session):void] notify_main_thread
163
+ # @attr [callback(:session, AudioFormat, :frames, :int):int] music_delivery
164
+ # @attr [callback(:session):void] play_token_lost
165
+ # @attr [callback(:session, :utf8_string):void] log_message
166
+ # @attr [callback(:session):void] end_of_track
167
+ # @attr [callback(:session, :error):void] streaming_error
168
+ # @attr [callback(:session):void] userinfo_updated
169
+ # @attr [callback(:session):void] start_playback
170
+ # @attr [callback(:session):void] stop_playback
171
+ # @attr [callback(:session, AudioBufferStats):void] get_audio_buffer_stats
172
+ # @attr [callback(:session)::void] offline_status_updated
173
+ class SessionCallbacks < FFI::Struct
174
+ layout :logged_in, callback([ :session, :error ], :void),
175
+ :logged_out, callback([ :session ], :void),
176
+ :metadata_updated, callback([ :session ], :void),
177
+ :connection_error, callback([ :session, :error ], :void),
178
+ :message_to_user, callback([ :session, :utf8_string ], :void),
179
+ :notify_main_thread, callback([ :session ], :void),
180
+ :music_delivery, callback([ :session, AudioFormat, :frames, :int ], :int),
181
+ :play_token_lost, callback([ :session ], :void),
182
+ :log_message, callback([ :session, :utf8_string ], :void),
183
+ :end_of_track, callback([ :session ], :void),
184
+ :streaming_error, callback([ :session, :error ], :void),
185
+ :userinfo_updated, callback([ :session ], :void),
186
+ :start_playback, callback([ :session ], :void),
187
+ :stop_playback, callback([ :session ], :void),
188
+ :get_audio_buffer_stats, callback([ :session, AudioBufferStats ], :void),
189
+ :offline_status_updated, callback([ :session ], :void),
190
+ :offline_error, callback([ :session, :error ], :void),
191
+ :credentials_blob_updated, callback([ :session, :string ], :void),
192
+ :connectionstate_updated, callback([ :session ], :void),
193
+ :scrobble_error, callback([ :session, :error ], :void),
194
+ :private_session_mode_changed, callback([ :session, :bool ], :void)
195
+ end
196
+
197
+ # FFI::Struct for Session configuration.
198
+ #
199
+ # @attr [Fixnum] api_version
200
+ # @attr [Pointer] cache_location
201
+ # @attr [Pointer] settings_location
202
+ # @attr [size_t] application_key_size
203
+ # @attr [Pointer] user_agent
204
+ # @attr [Pointer] callbacks
205
+ # @attr [Pointer] userdata
206
+ # @attr [Fixnum] dont_save_metadata_for_playlists
207
+ # @attr [Fixnum] initially_unload_playlists
208
+ class SessionConfig < FFI::Struct
209
+ layout :api_version, :int,
210
+ :cache_location, :string_pointer,
211
+ :settings_location, :string_pointer,
212
+ :application_key, :pointer,
213
+ :application_key_size, :size_t,
214
+ :user_agent, :string_pointer,
215
+ :callbacks, SessionCallbacks.by_ref,
216
+ :userdata, :userdata,
217
+ :compress_playlists, :bool,
218
+ :dont_save_metadata_for_playlists, :bool,
219
+ :initially_unload_playlists, :bool,
220
+ :device_id, :string_pointer,
221
+ :proxy, :string_pointer,
222
+ :proxy_username, :string_pointer,
223
+ :proxy_password, :string_pointer,
224
+ :tracefile, :string_pointer
225
+ end
226
+
227
+ # FFI::Struct for Offline Sync Status
228
+ #
229
+ # @attr [Fixnum] queued_tracks
230
+ # @attr [Fixnum] queued_bytes
231
+ # @attr [Fixnum] done_tracks
232
+ # @attr [Fixnum] done_bytes
233
+ # @attr [Fixnum] copied_tracks
234
+ # @attr [Fixnum] copied_bytes
235
+ # @attr [Fixnum] willnotcopy_tracks
236
+ # @attr [Fixnum] error_tracks
237
+ # @attr [Fixnum] syncing
238
+ class OfflineSyncStatus < FFI::Struct
239
+ layout :queued_tracks, :int,
240
+ :queued_bytes, :uint64,
241
+ :done_tracks, :int,
242
+ :done_bytes, :uint64,
243
+ :copied_tracks, :int,
244
+ :copied_bytes, :uint64,
245
+ :willnotcopy_tracks, :int,
246
+ :error_tracks, :int,
247
+ :syncing, :bool
248
+ end
249
+
250
+ #
251
+ enum :social_provider, [:spotify, :facebook, :lastfm]
252
+
253
+ #
254
+ enum :scrobbling_state, [:use_global_setting, :local_enabled, :local_disabled, :global_enabled, :global_disabled]
255
+
256
+ #
257
+ enum :connectionstate, [:logged_out, :logged_in, :disconnected, :undefined, :offline]
258
+
259
+ #
260
+ enum :connection_type, [:unknown, :none, :mobile, :mobile_roaming, :wifi, :wired]
261
+
262
+ #
263
+ enum :connection_rules, [:network , 0x1,
264
+ :network_if_roaming , 0x2,
265
+ :allow_sync_over_mobile, 0x4,
266
+ :allow_sync_over_wifi , 0x8]
267
+
268
+ attach_function :session_create, :sp_session_create, [ SessionConfig, :buffer_out ], :error
269
+ attach_function :session_release, :sp_session_release, [ :session ], :error
270
+
271
+ attach_function :session_process_events, :sp_session_process_events, [ :session, :buffer_out ], :error
272
+ attach_function :session_login, :sp_session_login, [ :session, :utf8_string, :string, :bool, :string ], :error
273
+ attach_function :session_relogin, :sp_session_relogin, [ :session ], :error
274
+ attach_function :session_forget_me, :sp_session_forget_me, [ :session ], :error
275
+ attach_function :session_remembered_user, :sp_session_remembered_user, [ :session, :buffer_out, :size_t ], :int
276
+
277
+ attach_function :session_user, :sp_session_user, [ :session ], :user
278
+ attach_function :session_logout, :sp_session_logout, [ :session ], :error
279
+ attach_function :session_connectionstate, :sp_session_connectionstate, [ :session ], :connectionstate
280
+ attach_function :session_userdata, :sp_session_userdata, [ :session ], :userdata
281
+ attach_function :session_set_cache_size, :sp_session_set_cache_size, [ :session, :size_t ], :error
282
+ attach_function :session_player_load, :sp_session_player_load, [ :session, :track ], :error
283
+ attach_function :session_player_seek, :sp_session_player_seek, [ :session, :int ], :error
284
+ attach_function :session_player_play, :sp_session_player_play, [ :session, :bool ], :error
285
+ attach_function :session_player_unload, :sp_session_player_unload, [ :session ], :error
286
+ attach_function :session_player_prefetch, :sp_session_player_prefetch, [ :session, :track ], :error
287
+ attach_function :session_playlistcontainer, :sp_session_playlistcontainer, [ :session ], :playlistcontainer
288
+ attach_function :session_inbox_create, :sp_session_inbox_create, [ :session ], :playlist
289
+ attach_function :session_starred_create, :sp_session_starred_create, [ :session ], :playlist
290
+ attach_function :session_starred_for_user_create, :sp_session_starred_for_user_create, [ :session, :utf8_string ], :playlist
291
+ attach_function :session_publishedcontainer_for_user_create, :sp_session_publishedcontainer_for_user_create, [ :playlist, :utf8_string ], :playlistcontainer
292
+ attach_function :session_preferred_bitrate, :sp_session_preferred_bitrate, [ :session, :bitrate ], :error
293
+
294
+ attach_function :session_set_connection_type, :sp_session_set_connection_type, [ :session, :connection_type ], :error
295
+ attach_function :session_set_connection_rules, :sp_session_set_connection_rules, [ :session, :connection_rules ], :error
296
+
297
+ attach_function :offline_tracks_to_sync, :sp_offline_tracks_to_sync, [ :session ], :int
298
+ attach_function :offline_num_playlists, :sp_offline_num_playlists, [ :session ], :int
299
+ attach_function :offline_sync_get_status, :sp_offline_sync_get_status, [ :session, OfflineSyncStatus ], :bool
300
+ attach_function :offline_time_left, :sp_offline_time_left, [ :session ], :int
301
+
302
+ attach_function :session_user_country, :sp_session_user_country, [ :session ], :int
303
+ attach_function :session_preferred_offline_bitrate, :sp_session_preferred_offline_bitrate, [ :session, :bitrate, :bool ], :error
304
+
305
+ attach_function :session_set_volume_normalization, :sp_session_set_volume_normalization, [ :session, :bool ], :error
306
+ attach_function :session_get_volume_normalization, :sp_session_get_volume_normalization, [ :session ], :bool
307
+
308
+ attach_function :session_flush_caches, :sp_session_flush_caches, [ :session ], :error
309
+ attach_function :session_user_name, :sp_session_user_name, [ :session ], :string
310
+
311
+ attach_function :session_set_private_session, :sp_session_set_private_session, [ :session, :bool ], :error
312
+ attach_function :session_is_private_session, :sp_session_is_private_session, [ :session ], :bool
313
+ attach_function :session_set_scrobbling, :sp_session_set_scrobbling, [ :session, :social_provider, :scrobbling_state ], :error
314
+ attach_function :session_is_scrobbling, :sp_session_is_scrobbling, [ :session, :social_provider, :buffer_out ], :error
315
+ attach_function :session_is_scrobbling_possible, :sp_session_is_scrobbling_possible, [ :session, :social_provider, :buffer_out ], :error
316
+ attach_function :session_set_social_credentials, :sp_session_set_social_credentials, [ :session, :social_provider, :utf8_string, :string ], :error
317
+
318
+ #
319
+ # Images
320
+ #
321
+ # @see http://developer.spotify.com/en/libspotify/docs/group__image.html
322
+
323
+ #
324
+ enum :imageformat, [:unknown, -1, :jpeg]
325
+ enum :image_size, [ :normal, :small, :large ]
326
+
327
+ callback :image_loaded_cb, [ :image, :userdata ], :void
328
+ attach_function :image_create, :sp_image_create, [ :session, :image_id ], :image
329
+ attach_function :image_add_load_callback, :sp_image_add_load_callback, [ :image, :image_loaded_cb, :userdata ], :error
330
+ attach_function :image_remove_load_callback, :sp_image_remove_load_callback, [ :image, :image_loaded_cb, :userdata ], :error
331
+ attach_function :image_is_loaded, :sp_image_is_loaded, [ :image ], :bool
332
+ attach_function :image_error, :sp_image_error, [ :image ], :error
333
+ attach_function :image_format, :sp_image_format, [ :image ], :imageformat
334
+ attach_function :image_data, :sp_image_data, [ :image, :buffer_out ], :pointer
335
+ attach_function :image_image_id, :sp_image_image_id, [ :image ], :image_id
336
+ attach_function :image_create_from_link, :sp_image_create_from_link, [ :session, :link ], :image
337
+
338
+ attach_function :image_add_ref, :sp_image_add_ref, [ :image ], :error
339
+ attach_function :image_release, :sp_image_release, [ :image ], :error
340
+
341
+
342
+ #
343
+ # Link
344
+ #
345
+ # @see http://developer.spotify.com/en/libspotify/docs/group__link.html
346
+
347
+ #
348
+ enum :linktype, [:invalid, :track, :album, :artist, :search,
349
+ :playlist, :profile, :starred, :localtrack, :image]
350
+
351
+ attach_function :link_create_from_string, :sp_link_create_from_string, [ :string ], :link
352
+ attach_function :link_create_from_track, :sp_link_create_from_track, [ :track, :int ], :link
353
+ attach_function :link_create_from_album, :sp_link_create_from_album, [ :album ], :link
354
+ attach_function :link_create_from_artist, :sp_link_create_from_artist, [ :artist ], :link
355
+ attach_function :link_create_from_search, :sp_link_create_from_search, [ :search ], :link
356
+ attach_function :link_create_from_playlist, :sp_link_create_from_playlist, [ :playlist ], :link
357
+ attach_function :link_create_from_artist_portrait, :sp_link_create_from_artist_portrait, [ :artist, :image_size ], :link
358
+ attach_function :link_create_from_artistbrowse_portrait, :sp_link_create_from_artistbrowse_portrait, [ :artistbrowse, :int ], :link
359
+ attach_function :link_create_from_album_cover, :sp_link_create_from_album_cover, [ :album, :image_size ], :link
360
+ attach_function :link_create_from_image, :sp_link_create_from_image, [ :image ], :link
361
+ attach_function :link_create_from_user, :sp_link_create_from_user, [ :user ], :link
362
+ attach_function :link_as_string, :sp_link_as_string, [ :link, :buffer_out, :int ], :int
363
+ attach_function :link_type, :sp_link_type, [ :link ], :linktype
364
+ attach_function :link_as_track, :sp_link_as_track, [ :link ], :track
365
+ attach_function :link_as_track_and_offset, :sp_link_as_track_and_offset, [ :link, :buffer_out ], :track
366
+ attach_function :link_as_album, :sp_link_as_album, [ :link ], :album
367
+ attach_function :link_as_artist, :sp_link_as_artist, [ :link ], :artist
368
+ attach_function :link_as_user, :sp_link_as_user, [ :link ], :user
369
+
370
+ attach_function :link_add_ref, :sp_link_add_ref, [ :link ], :error
371
+ attach_function :link_release, :sp_link_release, [ :link ], :error
372
+
373
+ #
374
+ # Tracks
375
+ #
376
+ # @see http://developer.spotify.com/en/libspotify/docs/group__track.html
377
+
378
+ enum :availability, [:unavailable, :available, :not_streamable, :banned_by_artist]
379
+ typedef :availability, :track_availability
380
+
381
+ enum :track_offline_status, [:no, :waiting, :downloading, :done, :error, :done_expired, :limit_exceeded, :done_resync]
382
+
383
+ #
384
+ attach_function :track_is_loaded, :sp_track_is_loaded, [ :track ], :bool
385
+ attach_function :track_error, :sp_track_error, [ :track ], :error
386
+ attach_function :track_get_availability, :sp_track_get_availability, [ :session, :track ], :track_availability
387
+ attach_function :track_is_local, :sp_track_is_local, [ :session, :track ], :bool
388
+ attach_function :track_is_autolinked, :sp_track_is_autolinked, [ :session, :track ], :bool
389
+ attach_function :track_is_starred, :sp_track_is_starred, [ :session, :track ], :bool
390
+ attach_function :track_set_starred, :sp_track_set_starred, [ :session, :array, :int, :bool ], :error
391
+ attach_function :track_num_artists, :sp_track_num_artists, [ :track ], :int
392
+ attach_function :track_artist, :sp_track_artist, [ :track, :int ], :artist
393
+ attach_function :track_album, :sp_track_album, [ :track ], :album
394
+ attach_function :track_name, :sp_track_name, [ :track ], :utf8_string
395
+ attach_function :track_duration, :sp_track_duration, [ :track ], :int
396
+ attach_function :track_popularity, :sp_track_popularity, [ :track ], :int
397
+ attach_function :track_disc, :sp_track_disc, [ :track ], :int
398
+ attach_function :track_index, :sp_track_index, [ :track ], :int
399
+ attach_function :track_is_placeholder, :sp_track_is_placeholder, [ :track ], :bool
400
+ attach_function :track_get_playable, :sp_track_get_playable, [ :session, :track ], :track
401
+
402
+ attach_function :track_offline_get_status, :sp_track_offline_get_status, [ :track ], :track_offline_status
403
+
404
+ attach_function :localtrack_create, :sp_localtrack_create, [ :utf8_string, :utf8_string, :utf8_string, :int ], :track
405
+
406
+ attach_function :track_add_ref, :sp_track_add_ref, [ :track ], :error
407
+ attach_function :track_release, :sp_track_release, [ :track ], :error
408
+
409
+ #
410
+ # Albums
411
+ #
412
+ # @see http://developer.spotify.com/en/libspotify/docs/group__album.html
413
+
414
+ #
415
+ enum :albumtype, [:album, :single, :compilation, :unknown]
416
+
417
+ attach_function :album_is_loaded, :sp_album_is_loaded, [ :album ], :bool
418
+ attach_function :album_is_available, :sp_album_is_available, [ :album ], :bool
419
+ attach_function :album_artist, :sp_album_artist, [ :album ], :artist
420
+ attach_function :album_cover, :sp_album_cover, [ :album, :image_size ], :image_id
421
+ attach_function :album_name, :sp_album_name, [ :album ], :utf8_string
422
+ attach_function :album_year, :sp_album_year, [ :album ], :int
423
+ attach_function :album_type, :sp_album_type, [ :album ], :albumtype
424
+
425
+ attach_function :album_add_ref, :sp_album_add_ref, [ :album ], :error
426
+ attach_function :album_release, :sp_album_release, [ :album ], :error
427
+
428
+ #
429
+ # Album Browser
430
+ #
431
+ # @see http://developer.spotify.com/en/libspotify/docs/group__albumbrowse.html
432
+
433
+ #
434
+ callback :albumbrowse_complete_cb, [:albumbrowse, :userdata], :void
435
+ attach_function :albumbrowse_create, :sp_albumbrowse_create, [ :session, :album, :albumbrowse_complete_cb, :userdata ], :albumbrowse
436
+ attach_function :albumbrowse_is_loaded, :sp_albumbrowse_is_loaded, [ :albumbrowse ], :bool
437
+ attach_function :albumbrowse_error, :sp_albumbrowse_error, [ :albumbrowse ], :error
438
+ attach_function :albumbrowse_album, :sp_albumbrowse_album, [ :albumbrowse ], :album
439
+ attach_function :albumbrowse_artist, :sp_albumbrowse_artist, [ :albumbrowse ], :artist
440
+ attach_function :albumbrowse_num_copyrights, :sp_albumbrowse_num_copyrights, [ :albumbrowse ], :int
441
+ attach_function :albumbrowse_copyright, :sp_albumbrowse_copyright, [ :albumbrowse, :int ], :utf8_string
442
+ attach_function :albumbrowse_num_tracks, :sp_albumbrowse_num_tracks, [ :albumbrowse ], :int
443
+ attach_function :albumbrowse_track, :sp_albumbrowse_track, [ :albumbrowse, :int ], :track
444
+ attach_function :albumbrowse_review, :sp_albumbrowse_review, [ :albumbrowse ], :utf8_string
445
+ attach_function :albumbrowse_backend_request_duration, :sp_albumbrowse_backend_request_duration, [ :albumbrowse ], :int
446
+
447
+ attach_function :albumbrowse_add_ref, :sp_albumbrowse_add_ref, [ :albumbrowse ], :error
448
+ attach_function :albumbrowse_release, :sp_albumbrowse_release, [ :albumbrowse ], :error
449
+
450
+ #
451
+ # Artists
452
+ #
453
+ # @see http://developer.spotify.com/en/libspotify/docs/group__artist.html
454
+
455
+ #
456
+ attach_function :artist_name, :sp_artist_name, [ :artist ], :utf8_string
457
+ attach_function :artist_is_loaded, :sp_artist_is_loaded, [ :artist ], :bool
458
+ attach_function :artist_portrait, :sp_artist_portrait, [ :artist, :image_size ], :image_id
459
+
460
+ attach_function :artist_add_ref, :sp_artist_add_ref, [ :artist ], :error
461
+ attach_function :artist_release, :sp_artist_release, [ :artist ], :error
462
+
463
+ #
464
+ # Artist Browsing
465
+ #
466
+ # @see http://developer.spotify.com/en/libspotify/docs/group__artistbrowse.html
467
+
468
+ enum :artistbrowse_type, [:full, :no_tracks, :no_albums]
469
+
470
+ #
471
+ callback :artistbrowse_complete_cb, [:artistbrowse, :userdata], :void
472
+ attach_function :artistbrowse_create, :sp_artistbrowse_create, [ :session, :artist, :artistbrowse_type, :artistbrowse_complete_cb, :userdata ], :artistbrowse
473
+ attach_function :artistbrowse_is_loaded, :sp_artistbrowse_is_loaded, [ :artistbrowse ], :bool
474
+ attach_function :artistbrowse_error, :sp_artistbrowse_error, [ :artistbrowse ], :error
475
+ attach_function :artistbrowse_artist, :sp_artistbrowse_artist, [ :artistbrowse ], :artist
476
+ attach_function :artistbrowse_num_portraits, :sp_artistbrowse_num_portraits, [ :artistbrowse ], :int
477
+ attach_function :artistbrowse_portrait, :sp_artistbrowse_portrait, [ :artistbrowse, :int ], :image_id
478
+ attach_function :artistbrowse_num_tracks, :sp_artistbrowse_num_tracks, [ :artistbrowse ], :int
479
+ attach_function :artistbrowse_track, :sp_artistbrowse_track, [ :artistbrowse, :int ], :track
480
+ attach_function :artistbrowse_num_albums, :sp_artistbrowse_num_albums, [ :artistbrowse ], :int
481
+ attach_function :artistbrowse_album, :sp_artistbrowse_album, [ :artistbrowse, :int ], :album
482
+ attach_function :artistbrowse_num_similar_artists, :sp_artistbrowse_num_similar_artists, [ :artistbrowse ], :int
483
+ attach_function :artistbrowse_similar_artist, :sp_artistbrowse_similar_artist, [ :artistbrowse, :int ], :artist
484
+ attach_function :artistbrowse_biography, :sp_artistbrowse_biography, [ :artistbrowse ], :utf8_string
485
+ attach_function :artistbrowse_backend_request_duration, :sp_artistbrowse_backend_request_duration, [ :artistbrowse ], :int
486
+ attach_function :artistbrowse_num_tophit_tracks, :sp_artistbrowse_num_tophit_tracks, [ :artistbrowse ], :int
487
+ attach_function :artistbrowse_tophit_track, :sp_artistbrowse_tophit_track, [ :artistbrowse, :int ], :track
488
+
489
+ attach_function :artistbrowse_add_ref, :sp_artistbrowse_add_ref, [ :artistbrowse ], :error
490
+ attach_function :artistbrowse_release, :sp_artistbrowse_release, [ :artistbrowse ], :error
491
+
492
+ #
493
+ # Searching
494
+ #
495
+ # @see http://developer.spotify.com/en/libspotify/docs/group__search.html
496
+
497
+ enum :search_type, [:standard, :suggest]
498
+
499
+ callback :search_complete_cb, [:search, :userdata], :void
500
+ attach_function :search_create, :sp_search_create, [ :session, :utf8_string, :int, :int, :int, :int, :int, :int, :int, :int, :search_type, :search_complete_cb, :userdata ], :search
501
+ attach_function :search_is_loaded, :sp_search_is_loaded, [ :search ], :bool
502
+ attach_function :search_error, :sp_search_error, [ :search ], :error
503
+ attach_function :search_query, :sp_search_query, [ :search ], :utf8_string
504
+ attach_function :search_did_you_mean, :sp_search_did_you_mean, [ :search ], :utf8_string
505
+ attach_function :search_num_tracks, :sp_search_num_tracks, [ :search ], :int
506
+ attach_function :search_track, :sp_search_track, [ :search, :int ], :track
507
+ attach_function :search_num_albums, :sp_search_num_albums, [ :search ], :int
508
+ attach_function :search_album, :sp_search_album, [ :search, :int ], :album
509
+ attach_function :search_num_artists, :sp_search_num_artists, [ :search ], :int
510
+ attach_function :search_artist, :sp_search_artist, [ :search, :int ], :artist
511
+ attach_function :search_num_playlists, :sp_search_num_playlists, [ :search ], :int
512
+ attach_function :search_playlist_name, :sp_search_playlist_name, [ :search, :int ], :utf8_string
513
+ attach_function :search_playlist_uri, :sp_search_playlist_uri, [ :search, :int ], :utf8_string
514
+ attach_function :search_playlist_image_uri, :sp_search_playlist_image_uri, [ :search, :int ], :utf8_string
515
+ attach_function :search_total_tracks, :sp_search_total_tracks, [ :search ], :int
516
+ attach_function :search_total_albums, :sp_search_total_albums, [ :search ], :int
517
+ attach_function :search_total_artists, :sp_search_total_artists, [ :search ], :int
518
+ attach_function :search_total_playlists, :sp_search_total_playlists, [ :search ], :int
519
+
520
+ attach_function :search_add_ref, :sp_search_add_ref, [ :search ], :error
521
+ attach_function :search_release, :sp_search_release, [ :search ], :error
522
+
523
+ #
524
+ # Playlists
525
+ #
526
+ # @see http://developer.spotify.com/en/libspotify/docs/group__playlist.html
527
+
528
+ # FFI::Struct for Playlist callbacks.
529
+ #
530
+ # @attr [callback(:playlist, :array, :int, :int, :userdata):void] tracks_added
531
+ # @attr [callback(:playlist, :array, :int, :userdata):void] tracks_removed
532
+ # @attr [callback(:playlist, :array, :int, :int, :userdata):void] tracks_moved
533
+ # @attr [callback(:playlist, :userdata):void] playlist_renamed
534
+ # @attr [callback(:playlist, :userdata):void] playlist_state_changed
535
+ # @attr [callback(:playlist, :bool, :userdata):void] playlist_update_in_progress
536
+ # @attr [callback(:playlist, :userdata):void] playlist_metadata_updated
537
+ # @attr [callback(:playlist, :int, :user, :int, :userdata):void] track_created_changed
538
+ # @attr [callback(:playlist, :int, :bool, :userdata):void] track_seen_changed
539
+ # @attr [callback(:playlist, :utf8_string, :userdata):void] description_changed
540
+ # @attr [callback(:playlist, :image_id, :userdata):void] image_changed
541
+ # @attr [callback(:playlist, :int, :utf8_string, :userdata):void] track_message_changed
542
+ # @attr [callback(:playlist, :userdata):void] subscribers_changed
543
+ class PlaylistCallbacks < FFI::Struct
544
+ layout :tracks_added, callback([ :playlist, :array, :int, :int, :userdata ], :void),
545
+ :tracks_removed, callback([ :playlist, :array, :int, :userdata ], :void),
546
+ :tracks_moved, callback([ :playlist, :array, :int, :int, :userdata ], :void),
547
+ :playlist_renamed, callback([ :playlist, :userdata ], :void),
548
+ :playlist_state_changed, callback([ :playlist, :userdata ], :void),
549
+ :playlist_update_in_progress, callback([ :playlist, :bool, :userdata ], :void),
550
+ :playlist_metadata_updated, callback([ :playlist, :userdata ], :void),
551
+ :track_created_changed, callback([ :playlist, :int, :user, :int, :userdata ], :void),
552
+ :track_seen_changed, callback([ :playlist, :int, :bool, :userdata ], :void),
553
+ :description_changed, callback([ :playlist, :utf8_string, :userdata ], :void),
554
+ :image_changed, callback([ :playlist, :image_id, :userdata ], :void),
555
+ :track_message_changed, callback([ :playlist, :int, :utf8_string, :userdata ], :void),
556
+ :subscribers_changed, callback([ :playlist, :userdata ], :void)
557
+ end
558
+
559
+ # FFI::Struct for Subscribers of a Playlist.
560
+ #
561
+ # @attr [Fixnum] count
562
+ # @attr [Array<Pointer<String>>] subscribers
563
+ class Subscribers < FFI::Struct
564
+ layout :count, :uint,
565
+ :subscribers, [:pointer, 1] # array of pointers to strings
566
+
567
+ # Redefined, as the layout of the Struct can only be determined
568
+ # at run-time.
569
+ #
570
+ # @param [FFI::Pointer] pointer
571
+ def initialize(pointer)
572
+ count = pointer.read_uint
573
+
574
+ layout = [:count, :uint]
575
+ layout += [:subscribers, [:pointer, count]] if count > 0
576
+
577
+ super(pointer, *layout)
578
+ end
579
+ end
580
+
581
+ #
582
+ enum :playlist_type, [:playlist, :start_folder, :end_folder, :placeholder]
583
+
584
+ #
585
+ enum :playlist_offline_status, [:no, :yes, :downloading, :waiting]
586
+
587
+ attach_function :playlist_is_loaded, :sp_playlist_is_loaded, [ :playlist ], :bool
588
+ attach_function :playlist_add_callbacks, :sp_playlist_add_callbacks, [ :playlist, PlaylistCallbacks, :userdata ], :error
589
+ attach_function :playlist_remove_callbacks, :sp_playlist_remove_callbacks, [ :playlist, PlaylistCallbacks, :userdata ], :error
590
+ attach_function :playlist_num_tracks, :sp_playlist_num_tracks, [ :playlist ], :int
591
+ attach_function :playlist_track, :sp_playlist_track, [ :playlist, :int ], :track
592
+ attach_function :playlist_track_create_time, :sp_playlist_track_create_time, [ :playlist, :int ], :int
593
+ attach_function :playlist_track_creator, :sp_playlist_track_creator, [ :playlist, :int ], :user
594
+ attach_function :playlist_track_seen, :sp_playlist_track_seen, [ :playlist, :int ], :bool
595
+ attach_function :playlist_track_set_seen, :sp_playlist_track_set_seen, [ :playlist, :int, :bool ], :error
596
+ attach_function :playlist_track_message, :sp_playlist_track_message, [ :playlist, :int ], :utf8_string
597
+ attach_function :playlist_name, :sp_playlist_name, [ :playlist ], :utf8_string
598
+ attach_function :playlist_rename, :sp_playlist_rename, [ :playlist, :utf8_string ], :error
599
+ attach_function :playlist_owner, :sp_playlist_owner, [ :playlist ], :user
600
+ attach_function :playlist_is_collaborative, :sp_playlist_is_collaborative, [ :playlist ], :bool
601
+ attach_function :playlist_set_collaborative, :sp_playlist_set_collaborative, [ :playlist, :bool ], :error
602
+ attach_function :playlist_set_autolink_tracks, :sp_playlist_set_autolink_tracks, [ :playlist, :bool ], :error
603
+ attach_function :playlist_get_description, :sp_playlist_get_description, [ :playlist ], :utf8_string
604
+ attach_function :playlist_get_image, :sp_playlist_get_image, [ :playlist, :buffer_out ], :bool
605
+ attach_function :playlist_has_pending_changes, :sp_playlist_has_pending_changes, [ :playlist ], :bool
606
+ attach_function :playlist_add_tracks, :sp_playlist_add_tracks, [ :playlist, :array, :int, :int, :session ], :error
607
+ attach_function :playlist_remove_tracks, :sp_playlist_remove_tracks, [ :playlist, :array, :int ], :error
608
+ attach_function :playlist_reorder_tracks, :sp_playlist_reorder_tracks, [ :playlist, :array, :int, :int ], :error
609
+ attach_function :playlist_num_subscribers, :sp_playlist_num_subscribers, [ :playlist ], :uint
610
+ attach_function :playlist_subscribers, :sp_playlist_subscribers, [ :playlist ], Subscribers
611
+ attach_function :playlist_subscribers_free, :sp_playlist_subscribers_free, [ Subscribers ], :error
612
+ attach_function :playlist_update_subscribers, :sp_playlist_update_subscribers, [ :session, :playlist ], :error
613
+ attach_function :playlist_is_in_ram, :sp_playlist_is_in_ram, [ :session, :playlist ], :bool
614
+ attach_function :playlist_set_in_ram, :sp_playlist_set_in_ram, [ :session, :playlist, :bool ], :error
615
+ attach_function :playlist_create, :sp_playlist_create, [ :session, :link ], :playlist
616
+ attach_function :playlist_get_offline_status, :sp_playlist_get_offline_status, [ :session, :playlist ], :playlist_offline_status
617
+ attach_function :playlist_get_offline_download_completed, :sp_playlist_get_offline_download_completed, [ :session, :playlist ], :int
618
+ attach_function :playlist_set_offline_mode, :sp_playlist_set_offline_mode, [ :session, :playlist, :bool ], :error
619
+
620
+ attach_function :playlist_add_ref, :sp_playlist_add_ref, [ :playlist ], :error
621
+ attach_function :playlist_release, :sp_playlist_release, [ :playlist ], :error
622
+
623
+ #
624
+ # Playlist Container
625
+ #
626
+
627
+ # FFI::Struct for the PlaylistContainer.
628
+ #
629
+ # @attr [callback(:playlistcontainer, :playlist, :int, :userdata):void] playlist_added
630
+ # @attr [callback(:playlistcontainer, :playlist, :int, :userdata):void] playlist_removed
631
+ # @attr [callback(:playlistcontainer, :playlist, :int, :int, :userdata):void] playlist_moved
632
+ # @attr [callback(:playlistcontainer, :userdata):void] container_loaded
633
+ class PlaylistContainerCallbacks < FFI::Struct
634
+ layout :playlist_added, callback([ :playlistcontainer, :playlist, :int, :userdata ], :void),
635
+ :playlist_removed, callback([ :playlistcontainer, :playlist, :int, :userdata ], :void),
636
+ :playlist_moved, callback([ :playlistcontainer, :playlist, :int, :int, :userdata ], :void),
637
+ :container_loaded, callback([ :playlistcontainer, :userdata ], :void)
638
+ end
639
+
640
+ #
641
+ attach_function :playlistcontainer_add_callbacks, :sp_playlistcontainer_add_callbacks, [ :playlistcontainer, PlaylistContainerCallbacks, :userdata ], :error
642
+ attach_function :playlistcontainer_remove_callbacks, :sp_playlistcontainer_remove_callbacks, [ :playlistcontainer, PlaylistContainerCallbacks, :userdata ], :error
643
+ attach_function :playlistcontainer_num_playlists, :sp_playlistcontainer_num_playlists, [ :playlistcontainer ], :int
644
+ attach_function :playlistcontainer_playlist, :sp_playlistcontainer_playlist, [ :playlistcontainer, :int ], :playlist
645
+ attach_function :playlistcontainer_playlist_type, :sp_playlistcontainer_playlist_type, [ :playlistcontainer, :int ], :playlist_type
646
+ attach_function :playlistcontainer_playlist_folder_name, :sp_playlistcontainer_playlist_folder_name, [ :playlistcontainer, :int, :buffer_out, :int ], :error
647
+ attach_function :playlistcontainer_playlist_folder_id, :sp_playlistcontainer_playlist_folder_id, [ :playlistcontainer, :int ], :uint64
648
+ attach_function :playlistcontainer_add_new_playlist, :sp_playlistcontainer_add_new_playlist, [ :playlistcontainer, :utf8_string ], :playlist
649
+ attach_function :playlistcontainer_add_playlist, :sp_playlistcontainer_add_playlist, [ :playlistcontainer, :link ], :playlist
650
+ attach_function :playlistcontainer_remove_playlist, :sp_playlistcontainer_remove_playlist, [ :playlistcontainer, :int ], :error
651
+ attach_function :playlistcontainer_move_playlist, :sp_playlistcontainer_move_playlist, [ :playlistcontainer, :int, :int, :bool ], :error
652
+ attach_function :playlistcontainer_add_folder, :sp_playlistcontainer_add_folder, [ :playlistcontainer, :int, :utf8_string ], :error
653
+ attach_function :playlistcontainer_owner, :sp_playlistcontainer_owner, [ :playlistcontainer ], :user
654
+ attach_function :playlistcontainer_is_loaded, :sp_playlistcontainer_is_loaded, [ :playlistcontainer ], :bool
655
+
656
+ attach_function :playlistcontainer_get_unseen_tracks, :sp_playlistcontainer_get_unseen_tracks, [ :playlistcontainer, :playlist, :array, :int ], :int
657
+ attach_function :playlistcontainer_clear_unseen_tracks, :sp_playlistcontainer_clear_unseen_tracks, [ :playlistcontainer, :playlist ], :int
658
+
659
+ attach_function :playlistcontainer_add_ref, :sp_playlistcontainer_add_ref, [ :playlistcontainer ], :error
660
+ attach_function :playlistcontainer_release, :sp_playlistcontainer_release, [ :playlistcontainer ], :error
661
+
662
+ #
663
+ # User handling
664
+ #
665
+ # @see http://developer.spotify.com/en/libspotify/docs/group__user.html
666
+
667
+ #
668
+ enum :relation_type, [:unknown, :none, :unidirectional, :bidirectional]
669
+
670
+ attach_function :user_canonical_name, :sp_user_canonical_name, [ :user ], :utf8_string
671
+ attach_function :user_display_name, :sp_user_display_name, [ :user ], :utf8_string
672
+ attach_function :user_is_loaded, :sp_user_is_loaded, [ :user ], :bool
673
+
674
+ attach_function :user_add_ref, :sp_user_add_ref, [ :user ], :error
675
+ attach_function :user_release, :sp_user_release, [ :user ], :error
676
+
677
+ #
678
+ # Toplists
679
+ #
680
+ # @see http://developer.spotify.com/en/libspotify/docs/group__toplist.html
681
+
682
+ #
683
+ enum :toplisttype, [:artists, :albums, :tracks]
684
+ enum :toplistregion, [:everywhere, :user]
685
+
686
+ callback :toplistbrowse_complete_cb, [:toplistbrowse, :userdata], :void
687
+ attach_function :toplistbrowse_create, :sp_toplistbrowse_create, [ :session, :toplisttype, :toplistregion, :utf8_string, :toplistbrowse_complete_cb, :userdata ], :toplistbrowse
688
+ attach_function :toplistbrowse_is_loaded, :sp_toplistbrowse_is_loaded, [ :toplistbrowse ], :bool
689
+ attach_function :toplistbrowse_error, :sp_toplistbrowse_error, [ :toplistbrowse ], :error
690
+ attach_function :toplistbrowse_num_artists, :sp_toplistbrowse_num_artists, [ :toplistbrowse ], :int
691
+ attach_function :toplistbrowse_artist, :sp_toplistbrowse_artist, [ :toplistbrowse, :int ], :artist
692
+ attach_function :toplistbrowse_num_albums, :sp_toplistbrowse_num_albums, [ :toplistbrowse ], :int
693
+ attach_function :toplistbrowse_album, :sp_toplistbrowse_album, [ :toplistbrowse, :int ], :album
694
+ attach_function :toplistbrowse_num_tracks, :sp_toplistbrowse_num_tracks, [ :toplistbrowse ], :int
695
+ attach_function :toplistbrowse_track, :sp_toplistbrowse_track, [ :toplistbrowse, :int ], :track
696
+ attach_function :toplistbrowse_backend_request_duration, :sp_toplistbrowse_backend_request_duration, [ :toplistbrowse ], :int
697
+
698
+ attach_function :toplistbrowse_add_ref, :sp_toplistbrowse_add_ref, [ :toplistbrowse ], :error
699
+ attach_function :toplistbrowse_release, :sp_toplistbrowse_release, [ :toplistbrowse ], :error
700
+
701
+ #
702
+ # Inbox
703
+ #
704
+ # @see http://developer.spotify.com/en/libspotify/docs/group__inbox.html
705
+
706
+ #
707
+ callback :inboxpost_complete_cb, [:inbox, :userdata], :void
708
+ attach_function :inbox_post_tracks, :sp_inbox_post_tracks, [ :session, :utf8_string, :array, :int, :utf8_string, :inboxpost_complete_cb, :userdata ], :inbox
709
+ attach_function :inbox_error, :sp_inbox_error, [ :inbox ], :error
710
+
711
+ attach_function :inbox_add_ref, :sp_inbox_add_ref, [ :inbox ], :error
712
+ attach_function :inbox_release, :sp_inbox_release, [ :inbox ], :error
713
+
714
+ # Rescue errors thrown when binding to a method that does not exist. Often
715
+ # this is because of the user using an old version of libspotify, or a new
716
+ # one. Either way it’s incompatible.
717
+ rescue FFI::NotFoundError => e
718
+ puts "An error was thrown when binding to the libspotify C functions. Please
719
+ make sure you are using an up-to-date libspotify version, compatible with
720
+ the current version of the Spotify gem.
721
+
722
+ Compatible versions of libspotify should be #{API_VERSION}.x.x
723
+
724
+ If it still does not work, see the CHANGELOG for information about which
725
+ libspotify version the gem was last updated to work with on GitHub:
726
+ https://github.com/Burgestrand/libspotify-ruby/blob/master/CHANGELOG.md
727
+ ".gsub(/^ +/, "")
728
+
729
+ raise
730
+ end