spotify 12.0.0 → 12.0.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -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