spotify 12.5.3 → 12.6.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (104) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +2 -0
  3. data/.travis.yml +20 -5
  4. data/CHANGELOG.md +29 -1
  5. data/Gemfile +5 -0
  6. data/MIT-LICENSE +21 -0
  7. data/README.markdown +75 -50
  8. data/Rakefile +1 -1
  9. data/examples/example-audio_delivery_speed.rb +48 -0
  10. data/examples/{audio-stream_example.rb → example-audio_stream.rb} +14 -29
  11. data/examples/example-console.rb +9 -0
  12. data/examples/example-listing_playlists.rb +89 -0
  13. data/examples/example-loading_object.rb +25 -0
  14. data/examples/example-random_related_artists.rb +53 -0
  15. data/examples/support.rb +106 -0
  16. data/lib/spotify.rb +36 -55
  17. data/lib/spotify/api.rb +54 -26
  18. data/lib/spotify/api/album.rb +45 -2
  19. data/lib/spotify/api/album_browse.rb +81 -3
  20. data/lib/spotify/api/artist.rb +21 -2
  21. data/lib/spotify/api/artist_browse.rb +121 -3
  22. data/lib/spotify/api/error.rb +5 -1
  23. data/lib/spotify/api/image.rb +72 -6
  24. data/lib/spotify/api/inbox.rb +33 -4
  25. data/lib/spotify/api/link.rb +117 -4
  26. data/lib/spotify/api/miscellaneous.rb +12 -0
  27. data/lib/spotify/api/playlist.rb +321 -16
  28. data/lib/spotify/api/playlist_container.rb +168 -9
  29. data/lib/spotify/api/search.rb +156 -3
  30. data/lib/spotify/api/session.rb +390 -26
  31. data/lib/spotify/api/toplist_browse.rb +74 -3
  32. data/lib/spotify/api/track.rb +134 -4
  33. data/lib/spotify/api/user.rb +18 -2
  34. data/lib/spotify/api_helpers.rb +47 -0
  35. data/lib/spotify/data_converters.rb +7 -0
  36. data/lib/spotify/{types → data_converters}/best_effort_string.rb +1 -1
  37. data/lib/spotify/{types → data_converters}/byte_string.rb +0 -0
  38. data/lib/spotify/data_converters/country_code.rb +30 -0
  39. data/lib/spotify/{types → data_converters}/image_id.rb +1 -1
  40. data/lib/spotify/{type_safety.rb → data_converters/type_safety.rb} +0 -0
  41. data/lib/spotify/{types → data_converters}/utf8_string.rb +2 -2
  42. data/lib/spotify/{types → data_converters}/utf8_string_pointer.rb +2 -2
  43. data/lib/spotify/error.rb +180 -47
  44. data/lib/spotify/managed_pointer.rb +32 -12
  45. data/lib/spotify/monkey_patches/ffi_buffer.rb +11 -0
  46. data/lib/spotify/monkey_patches/ffi_enums.rb +4 -0
  47. data/lib/spotify/monkey_patches/ffi_pointer.rb +1 -0
  48. data/lib/spotify/structs.rb +4 -0
  49. data/lib/spotify/structs/session_callbacks.rb +97 -26
  50. data/lib/spotify/structs/session_config.rb +1 -1
  51. data/lib/spotify/structs/subscribers.rb +4 -3
  52. data/lib/spotify/types.rb +104 -5
  53. data/lib/spotify/{objects → types}/album.rb +0 -0
  54. data/lib/spotify/{objects → types}/album_browse.rb +0 -0
  55. data/lib/spotify/{objects → types}/artist.rb +0 -0
  56. data/lib/spotify/{objects → types}/artist_browse.rb +0 -0
  57. data/lib/spotify/{objects → types}/image.rb +0 -0
  58. data/lib/spotify/{objects → types}/inbox.rb +0 -0
  59. data/lib/spotify/{objects → types}/link.rb +0 -0
  60. data/lib/spotify/{objects → types}/playlist.rb +0 -0
  61. data/lib/spotify/{objects → types}/playlist_container.rb +0 -0
  62. data/lib/spotify/{objects → types}/search.rb +0 -0
  63. data/lib/spotify/{objects → types}/session.rb +0 -0
  64. data/lib/spotify/{objects → types}/toplist_browse.rb +0 -0
  65. data/lib/spotify/{objects → types}/track.rb +0 -0
  66. data/lib/spotify/{objects → types}/user.rb +0 -0
  67. data/lib/spotify/util.rb +38 -35
  68. data/lib/spotify/version.rb +1 -1
  69. data/spec/spec_helper.rb +24 -13
  70. data/spec/spotify/api/image_spec.rb +32 -0
  71. data/spec/spotify/api/inbox_spec.rb +34 -0
  72. data/spec/spotify/api/link_spec.rb +40 -0
  73. data/spec/spotify/api/playlist_spec.rb +99 -0
  74. data/spec/spotify/api/playlistcontainer_spec.rb +82 -0
  75. data/spec/spotify/api/session_spec.rb +97 -0
  76. data/spec/spotify/api/track_spec.rb +29 -0
  77. data/spec/spotify/api_error_spec.rb +55 -0
  78. data/spec/spotify/api_spec.rb +17 -11
  79. data/spec/spotify/{types → data_converters}/best_effort_string_spec.rb +4 -4
  80. data/spec/spotify/{types → data_converters}/byte_string_spec.rb +0 -0
  81. data/spec/spotify/data_converters/country_code_spec.rb +16 -0
  82. data/spec/spotify/{types → data_converters}/image_id_spec.rb +1 -1
  83. data/spec/spotify/{type_safety_spec.rb → data_converters/type_safety_spec.rb} +0 -0
  84. data/spec/spotify/{types → data_converters}/utf8_string_pointer_spec.rb +0 -0
  85. data/spec/spotify/{types → data_converters}/utf8_string_spec.rb +1 -1
  86. data/spec/spotify/{api/functions_spec.rb → functions_spec.rb} +2 -0
  87. data/spec/spotify/managed_pointer_spec.rb +13 -13
  88. data/spec/spotify/structs/subscribers_spec.rb +5 -3
  89. data/spec/spotify/{defines_spec.rb → types_spec.rb} +16 -3
  90. data/spec/spotify/util_spec.rb +24 -0
  91. data/spec/spotify_spec.rb +74 -0
  92. data/spec/support/spotify_util.rb +6 -2
  93. data/spec/support/spy_output.rb +16 -0
  94. data/spotify.gemspec +4 -2
  95. metadata +111 -71
  96. data/examples/README.md +0 -15
  97. data/examples/console_example.rb +0 -22
  98. data/examples/example_support.rb +0 -66
  99. data/examples/loading-object_example.rb +0 -43
  100. data/examples/logging-in_example.rb +0 -58
  101. data/lib/spotify/defines.rb +0 -109
  102. data/lib/spotify/objects.rb +0 -17
  103. data/spec/spotify/enums_spec.rb +0 -9
  104. data/spec/spotify/spotify_spec.rb +0 -69
@@ -1,27 +1,180 @@
1
1
  module Spotify
2
2
  class API
3
3
  # @!group Search
4
+
5
+ # Fire off a search query for tracks, albums, artists, and playlists.
6
+ #
7
+ # @example
8
+ # callback = proc { |search| puts "Search results are available!" }
9
+ # search = Spotify.search_create(session, "Zanarkand", 0, 10, 0, 10, 0, 10, 0, 10, :standard, callback, nil)
10
+ #
11
+ # @note it is *very* important that the callback is not garbage collected before it is called!
12
+ # @param [Session] session
13
+ # @param [String] query
14
+ # @param [Integer] track_offset
15
+ # @param [Integer] track_count
16
+ # @param [Integer] album_offset
17
+ # @param [Integer] album_count
18
+ # @param [Integer] artist_offset
19
+ # @param [Integer] artist_count
20
+ # @param [Integer] playlist_offset
21
+ # @param [Integer] playlist_count
22
+ # @param [Integer] search_type one of :standard, or :suggest
23
+ # @param [Proc<Search, FFI::Pointer>] callback
24
+ # @param [FFI::Pointer] userdata
25
+ # @return [Search] a search
26
+ # @method search_create(session, query, track_offset, track_count, album_offset, album_count, artist_offset, artist_count, playlist_offset, playlist_count, search_type, callback, userdata)
4
27
  attach_function :search_create, [ Session, UTF8String, :int, :int, :int, :int, :int, :int, :int, :int, :search_type, :search_complete_cb, :userdata ], Search
28
+
29
+ # @param [Search] search
30
+ # @return [Boolean] true if the search has completed
31
+ # @method search_is_loaded(search)
5
32
  attach_function :search_is_loaded, [ Search ], :bool
6
- attach_function :search_error, [ Search ], :error
33
+
34
+ # @param [Search] search
35
+ # @return [Symbol] error code
36
+ # @method search_error(search)
37
+ attach_function :search_error, [ Search ], APIError
38
+
39
+ # @param [Search] search
40
+ # @return [String] search query
41
+ # @method search_query(search)
7
42
  attach_function :search_query, [ Search ], UTF8String
43
+
44
+ # @see #search_is_loaded
45
+ # @note if the search is not loaded, the function always return an empty string.
46
+ # @param [Search] search
47
+ # @return [String] spotify's guess at what the query might have meant instead
48
+ # @method search_did_you_mean(search)
8
49
  attach_function :search_did_you_mean, [ Search ], UTF8String
50
+
51
+ # @see #search_is_loaded
52
+ # @see #search_total_tracks
53
+ # @note if {#search_total_tracks} is larger than this number, you may retrieve additional
54
+ # results if you make the same search query again, but with a higher track_offset
55
+ # @note if the search is not loaded, the function always return 0.
56
+ # @param [Search] search
57
+ # @return [Integer] number of tracks in the search result
58
+ # @method search_num_tracks(search)
9
59
  attach_function :search_num_tracks, [ Search ], :int
60
+
61
+ # @see #search_num_tracks
62
+ # @note if index is out of range, the function always return nil.
63
+ # @param [Search] search
64
+ # @param [Integer] index number between 0...{#search_num_tracks}
65
+ # @return [Track, nil] track at index
66
+ # @method search_track(search, index)
10
67
  attach_function :search_track, [ Search, :int ], Track
68
+
69
+ # @see #search_is_loaded
70
+ # @see #search_total_albums
71
+ # @note if {#search_total_albums} is larger than this number, you may retrieve additional
72
+ # results if you make the same search query again, but with a higher album_offset
73
+ # @note if the search is not loaded, the function always return 0.
74
+ # @param [Search] search
75
+ # @return [Integer] number of albums in the search result
76
+ # @method search_num_albums(search)
11
77
  attach_function :search_num_albums, [ Search ], :int
78
+
79
+ # @see #search_num_albums
80
+ # @note if index is out of range, the function always return nil.
81
+ # @param [Search] search
82
+ # @param [Integer] index number between 0...{#search_num_albums}
83
+ # @return [Album, nil] album at index
84
+ # @method search_album(search, index)
12
85
  attach_function :search_album, [ Search, :int ], Album
86
+
87
+ # @see #search_is_loaded
88
+ # @see #search_total_artists
89
+ # @note if {#search_total_artists} is larger than this number, you may retrieve additional
90
+ # results if you make the same search query again, but with a higher artist_offset
91
+ # @note if the search is not loaded, the function always return 0.
92
+ # @param [Search] search
93
+ # @return [Integer] number of artists in the search result
94
+ # @method search_num_artists(search)
13
95
  attach_function :search_num_artists, [ Search ], :int
96
+
97
+ # @see #search_num_artists
98
+ # @note if index is out of range, the function always return nil.
99
+ # @param [Search] search
100
+ # @param [Integer] index number between 0...{#search_num_artists}
101
+ # @return [Artist, nil] artist at index
102
+ # @method search_artist(search, index)
14
103
  attach_function :search_artist, [ Search, :int ], Artist
104
+
105
+ # @see #search_is_loaded
106
+ # @see #search_total_playlists
107
+ # @note if {#search_total_playlists} is larger than this number, you may retrieve additional
108
+ # results if you make the same search query again, but with a higher playlist_offset
109
+ # @note if the search is not loaded, the function always return 0.
110
+ # @param [Search] search
111
+ # @return [Integer] number of playlists in the search result
112
+ # @method search_num_playlists(search)
15
113
  attach_function :search_num_playlists, [ Search ], :int
114
+
115
+ # @see #search_num_playlists
116
+ # @note if index is out of range, the function always return nil.
117
+ # @param [Search] search
118
+ # @param [Integer] index number between 0...{#search_num_playlists}
119
+ # @return [Playlist, nil] playlist at index
120
+ # @method search_playlist(search, index)
16
121
  attach_function :search_playlist, [ Search, :int ], Playlist
122
+
123
+ # @see #search_num_playlists
124
+ # @note if index is out of range, the function always return nil.
125
+ # @param [Search] search
126
+ # @param [Integer] index number between 0...{#search_num_playlists}
127
+ # @return [String, nil] name for playlist at index
128
+ # @method search_playlist_name(search, index)
17
129
  attach_function :search_playlist_name, [ Search, :int ], UTF8String
130
+
131
+ # @see #link_create_from_string
132
+ # @see #search_num_playlists
133
+ # @note if index is out of range, the function always return nil.
134
+ # @param [Search] search
135
+ # @param [Integer] index number between 0...{#search_num_playlists}
136
+ # @return [String, nil] spotify uri for playlist at index
137
+ # @method search_playlist_uri(search, index)
18
138
  attach_function :search_playlist_uri, [ Search, :int ], UTF8String
139
+
140
+ # @see #image_create_from_link
141
+ # @see #search_num_playlists
142
+ # @note if index is out of range, the function always return nil.
143
+ # @param [Search] search
144
+ # @param [Integer] index number between 0...{#search_num_playlists}
145
+ # @return [String, nil] image uri for playlist at index
146
+ # @method search_playlist_image_uri(search, index)
19
147
  attach_function :search_playlist_image_uri, [ Search, :int ], UTF8String
148
+
149
+ # @see #search_is_loaded
150
+ # @note if the search is not loaded, the function always return 0.
151
+ # @param [Search] search
152
+ # @return [Integer] number of total tracks in the search result
153
+ # @method search_total_tracks(search)
20
154
  attach_function :search_total_tracks, [ Search ], :int
155
+
156
+ # @see #search_is_loaded
157
+ # @note if the search is not loaded, the function always return 0.
158
+ # @param [Search] search
159
+ # @return [Integer] number of total albums in the search result
160
+ # @method search_total_albums(search)
21
161
  attach_function :search_total_albums, [ Search ], :int
162
+
163
+ # @see #search_is_loaded
164
+ # @note if the search is not loaded, the function always return 0.
165
+ # @param [Search] search
166
+ # @return [Integer] number of total artists in the search result
167
+ # @method search_total_artists(search)
22
168
  attach_function :search_total_artists, [ Search ], :int
169
+
170
+ # @see #search_is_loaded
171
+ # @note if the search is not loaded, the function always return 0.
172
+ # @param [Search] search
173
+ # @return [Integer] number of total playlists in the search result
174
+ # @method search_total_playlists(search)
23
175
  attach_function :search_total_playlists, [ Search ], :int
24
- attach_function :search_add_ref, [ Search ], :error
25
- attach_function :search_release, [ Search ], :error
176
+
177
+ attach_function :search_add_ref, [ Search ], APIError
178
+ attach_function :search_release, [ Search ], APIError
26
179
  end
27
180
  end
@@ -1,46 +1,410 @@
1
1
  module Spotify
2
2
  class API
3
3
  # @!group Session
4
- attach_function :session_create, [ SessionConfig.by_ref, :buffer_out ], :error
5
- attach_function :session_release, [ Session ], :error
6
- attach_function :session_process_events, [ Session, :buffer_out ], :error
7
- attach_function :session_login, [ Session, UTF8String, UTF8String, :bool, UTF8String ], :error
8
- attach_function :session_relogin, [ Session ], :error
9
- attach_function :session_forget_me, [ Session ], :error
10
- attach_function :session_remembered_user, [ Session, :buffer_out, :size_t ], :int
4
+
5
+ # @example
6
+ # $callbacks = Spotify::SessionCallbacks.new({
7
+ # connectionstate_updated: proc do |session|
8
+ # puts "New connection state: #{Spotify.session_connectionstate(session)}."
9
+ # end,
10
+ # music_delivery: proc do |session, format, frames, num_frames|
11
+ # puts "More audio coming through!"
12
+ # end,
13
+ # })
14
+ #
15
+ # config = {
16
+ # api_version: Spotify::API_VERSION.to_i,
17
+ # application_key: File.binread("./spotify_appkey.key"),
18
+ # cache_location: "",
19
+ # user_agent: "spotify for ruby",
20
+ # callbacks: $callbacks,
21
+ # }
22
+ #
23
+ # error, session = Spotify.session_create(config)
24
+ # raise Spotify::APIError.new(error) if error
25
+ #
26
+ # @note it is *very* important that the callbacks are not garbage collected while they may be called!
27
+ # @param [SessionConfig] config
28
+ # @return [Array<Symbol, Session>] a tuple of error code, and session
29
+ # @method session_create(config)
30
+ attach_function :session_create, [ SessionConfig.by_ref, :buffer_out ], APIError do |config|
31
+ config = Spotify::SessionConfig.new(config.to_h)
32
+
33
+ with_buffer(Spotify::Session) do |session_buffer|
34
+ error = sp_session_create(config, session_buffer)
35
+ error = nil if error == :ok
36
+
37
+ session = if error.nil?
38
+ Spotify::Session.from_native(session_buffer.read_pointer, nil)
39
+ end
40
+
41
+ [error, session]
42
+ end
43
+ end
44
+
45
+ attach_function :session_release, [ Session ], APIError
46
+
47
+ # Tell libspotify to process pending events from the backend.
48
+ #
49
+ # This will download changes and updates from Spotify, while simultaneously also uploading changes
50
+ # made locally, such as tracks added to playlists and more.
51
+ #
52
+ # This method is the cornerstone of libspotify. It should be called frequently to synchronize data.
53
+ # This method is also responsible for calling most callbacks.
54
+ #
55
+ # @example
56
+ # Spotify.session_process_events(session) # => 1337
57
+ #
58
+ # @param [Session] session
59
+ # @return [Integer] time (in milliseconds) until you should call process_events again
60
+ # @method session_process_events(session)
61
+ attach_function :session_process_events, [ Session, :buffer_out ], APIError do |session|
62
+ with_buffer(:int) do |timeout_buffer|
63
+ sp_session_process_events(session, timeout_buffer)
64
+ timeout_buffer.read_int
65
+ end
66
+ end
67
+
68
+ # Schedule a login.
69
+ #
70
+ # @see #session_process_events
71
+ # @see #session_relogin
72
+ # @note Login happens in the background. You have to process events a few times before you are logged in.
73
+ # @param [Session] session
74
+ # @param [String] username spotify username, or facebook e-mail
75
+ # @param [String] password spotify password, or facebook password, or nil
76
+ # @param [Boolean] remember_me true if {#session_relogin} should be possible
77
+ # @param [String] password_blob an alternative to password, stored from credentials_blob_updated session callback
78
+ # @return [Symbol] error code
79
+ # @method session_login(session, username, password, remember_me, password_blob)
80
+ attach_function :session_login, [ Session, UTF8String, UTF8String, :bool, UTF8String ], APIError
81
+
82
+ # Log in a previously remembered login from {#session_login}.
83
+ #
84
+ # You would use this after terminating your application, and later starting it again,
85
+ # assuming {#session_remembered_user} contains a username that is remembered.
86
+ #
87
+ # @see #session_login
88
+ # @see #session_process_events
89
+ # @note You must call {#session_logout} for remembered credentials to be stored.
90
+ # @note Login happens in the background. You have to process events a few times before you are logged in.
91
+ # @param [Session] session
92
+ # @return [Symbol] error code
93
+ # @method session_relogin(session)
94
+ attach_function :session_relogin, [ Session ], APIError
95
+
96
+ # Forget a previously remembered user.
97
+ #
98
+ # @see #session_relogin
99
+ # @param [Session] session
100
+ # @return [Symbol] error code
101
+ # @method session_forget_me(session)
102
+ attach_function :session_forget_me, [ Session ], APIError
103
+
104
+ # Retrieve the remembered user from {#session_login}.
105
+ #
106
+ # This is the user that will be logged in if you use {#session_relogin}.
107
+ #
108
+ # @example
109
+ # Spotify.session_remembered_user(session) # => "Burgestrand"
110
+ #
111
+ # @param [Session] session
112
+ # @return [String, nil] username of the remembered user, or nil if there was none
113
+ # @method session_remembered_user(session)
114
+ attach_function :session_remembered_user, [ Session, :buffer_out, :size_t ], :int do |session|
115
+ username_length = sp_session_remembered_user(session, nil, 0)
116
+ username = with_string_buffer(username_length) do |username_buffer, size|
117
+ sp_session_remembered_user(session, username_buffer, size)
118
+ end
119
+ username unless username.empty?
120
+ end
121
+
122
+ # @param [Session] session
123
+ # @return [User, nil] currently logged in user
124
+ # @method session_user(session)
11
125
  attach_function :session_user, [ Session ], User
12
- attach_function :session_logout, [ Session ], :error
126
+
127
+ # Schedule a logout.
128
+ #
129
+ # @note This updates credentials in remember_me from {#session_login} and {#session_forget_me}.
130
+ # @note Logout happen asynchronously. You need to call {#session_process_events} a little while.
131
+ # @param [Session] session
132
+ # @return [Symbol] error code
133
+ # @method session_logout(session)
134
+ attach_function :session_logout, [ Session ], APIError
135
+
136
+ # @param [Session] session
137
+ # @return [Symbol] current session connection state, one of :logged_out, :logged_in, :disconnected, :undefined, :offline
138
+ # @method session_connectionstate(session)
13
139
  attach_function :session_connectionstate, [ Session ], :connectionstate
140
+
141
+ # @param [Session] session
142
+ # @return [FFI::Pointer] userdata from config in {#session_create}
143
+ # @method session_userdata(session)
14
144
  attach_function :session_userdata, [ Session ], :userdata
15
- attach_function :session_set_cache_size, [ Session, :size_t ], :error
16
- attach_function :session_player_load, [ Session, Track ], :error
17
- attach_function :session_player_seek, [ Session, :int ], :error
18
- attach_function :session_player_play, [ Session, :bool ], :error
19
- attach_function :session_player_unload, [ Session ], :error
20
- attach_function :session_player_prefetch, [ Session, Track ], :error
145
+
146
+ # Set the allowed disk cache size used by libspotify.
147
+ #
148
+ # @param [Session] session
149
+ # @param [Integer] cache_size maximum cache size in megabytes, 0 means libspotify automatically resize cache as needed
150
+ # @return [Symbol] error code
151
+ # @method session_set_cache_size(session, cache_size)
152
+ attach_function :session_set_cache_size, [ Session, :size_t ], APIError
153
+
154
+ # Load the specified track for playback.
155
+ #
156
+ # When the the function returns, the track will have been loaded assuming there as no error.
157
+ #
158
+ # @param [Session] session
159
+ # @param [Track] track
160
+ # @return [Symbol] error code
161
+ # @method session_player_load(session, track)
162
+ attach_function :session_player_load, [ Session, Track ], APIError
163
+
164
+ # Seek to position in the currently loaded track.
165
+ #
166
+ # @see #session_player_load
167
+ # @param [Session] session
168
+ # @param [Integer] position in milliseconds
169
+ # @return [Symbol] error code
170
+ # @method session_player_seek(session, position)
171
+ attach_function :session_player_seek, [ Session, :int ], APIError
172
+
173
+ # Play or pause the currently loaded track.
174
+ #
175
+ # This will start delivery of audio frames to the music_delivery callback in {#session_create}.
176
+ # However, playback should wait until {SessionCallbacks#start_playback} callback is called by libspotify.
177
+ #
178
+ # @see #session_player_load
179
+ # @param [Session] session
180
+ # @param [Boolean] play if set to true, playback will be resumed, if set to false playback will be paused
181
+ # @return [Symbol] error code
182
+ # @method session_player_play(session, play)
183
+ attach_function :session_player_play, [ Session, :bool ], APIError
184
+
185
+ # Stop playback and clear the currently loaded track.
186
+ #
187
+ # @see #session_player_load
188
+ # @param [Session] session
189
+ # @return [Symbol] error code
190
+ # @method session_player_unload(session)
191
+ attach_function :session_player_unload, [ Session ], APIError
192
+
193
+ # Tell libspotify to start preloading a track so that {#session_player_load} has less work to do.
194
+ #
195
+ # This could be done towards the end of a track in a queue, before starting playing the next.
196
+ #
197
+ # @note prefetching is only possible if using a cache from config in {#session_create}
198
+ # @param [Session] session
199
+ # @param [Track] track
200
+ # @return [Symbol] error code
201
+ # @method session_player_prefetch(session, track)
202
+ attach_function :session_player_prefetch, [ Session, Track ], APIError
203
+
204
+ # @note if not logged in, the function always return nil.
205
+ # @param [Session] session
206
+ # @return [PlaylistContainer, nil] playlist container for currently logged in user
207
+ # @method session_playlistcontainer(session)
21
208
  attach_function :session_playlistcontainer, [ Session ], PlaylistContainer
209
+
210
+ # @note if not logged in, the function always return nil.
211
+ # @param [Session] session
212
+ # @return [Playlist] inbox playlist for currently logged in user (playlist where items sent by other users are posted to)
213
+ # @method session_inbox_create(session)
22
214
  attach_function :session_inbox_create, [ Session ], Playlist
215
+
216
+ # @note if not logged in, the function always return nil.
217
+ # @param [Session] session
218
+ # @return [Playlist, nil] starred playlist for currently logged in user
219
+ # @method session_starred_create(session)
23
220
  attach_function :session_starred_create, [ Session ], Playlist
221
+
222
+ # @note if not logged in, the function always return nil.
223
+ # @param [Session] session
224
+ # @param [String] username canonical username of user
225
+ # @return [Playlist, nil] starred playlist for the specified user
226
+ # @method session_starred_for_user_create(session, username)
24
227
  attach_function :session_starred_for_user_create, [ Session, UTF8String ], Playlist
228
+
229
+ # @note if not logged in, the function always return nil.
230
+ # @param [Session] session
231
+ # @param [String] username canonical username of user
232
+ # @return [PlaylistContainer, nil] published playlists container for the specified user
233
+ # @method session_publishedcontainer_for_user_create(session, username)
25
234
  attach_function :session_publishedcontainer_for_user_create, [ Session, UTF8String ], PlaylistContainer
26
- attach_function :session_preferred_bitrate, [ Session, :bitrate ], :error
27
- attach_function :session_set_connection_type, [ Session, :connection_type ], :error
28
- attach_function :session_set_connection_rules, [ Session, :connection_rules ], :error
235
+
236
+ # Set preferred bitrate for music streaming.
237
+ #
238
+ # @param [Session] session
239
+ # @param [Symbol] bitrate one of :160k, :320k, :96k
240
+ # @return [Symbol] error code
241
+ # @method session_preferred_bitrate(session, bitrate)
242
+ attach_function :session_preferred_bitrate, [ Session, :bitrate ], APIError
243
+
244
+ # Set current connection type.
245
+ #
246
+ # @see #session_set_connection_rules
247
+ # @param [Session] session
248
+ # @param [Symbol] type one of :unknown, :none, :mobile, :mobile_roaming, :wifi, :wired
249
+ # @return [Symbol] error code
250
+ # @method session_set_connection_type(session, type)
251
+ attach_function :session_set_connection_type, [ Session, :connection_type ], APIError
252
+
253
+ # Set rules for how libspotify connects to Spotify servers and synchronizes offline content.
254
+ #
255
+ # @example
256
+ # online_mode = Spotify::Util.enum_value!(:network, :connection_rules)
257
+ # over_wifi = Spotify::Util.enum_value!(:allow_sync_over_wifi, :connection_rules)
258
+ # Spotify.session_set_connection_rules($session, online_mode | over_wifi) # => :ok
259
+ #
260
+ # @see #session_set_connection_type
261
+ # @param [Session] session
262
+ # @param [Symbol] rules any of :network, :network_if_roaming, :allow_sync_over_mobile, :allow_sync_over_wifi
263
+ # @return [Symbol] error code
264
+ # @method session_set_connection_rules(session, rules)
265
+ attach_function :session_set_connection_rules, [ Session, :connection_rules ], APIError
266
+
267
+ # @param [Session] session
268
+ # @return [Integer] total number of tracks left to sync before all offline content has downloaded
269
+ # @method offline_tracks_to_sync(session)
29
270
  attach_function :offline_tracks_to_sync, [ Session ], :int
271
+
272
+ # @param [Session] session
273
+ # @return [Integer] total number of playlists marked for offline synchronization
274
+ # @method offline_num_playlists(session)
30
275
  attach_function :offline_num_playlists, [ Session ], :int
276
+
277
+ # @example
278
+ # status = Spotify::OfflineSyncStatus.new
279
+ # Spotify.offline_sync_get_status(session, status)
280
+ # p status.to_h # => { queued_tracks: 0, queued_bytes: 0, … }
281
+ #
282
+ # @param [Session] session
283
+ # @param [OfflineSyncStatus] status
284
+ # @return [Boolean] true if offline synching is enabled
285
+ # @method offline_sync_get_status(session, offline_sync_status)
31
286
  attach_function :offline_sync_get_status, [ Session, OfflineSyncStatus.by_ref ], :bool
287
+
288
+ # @param [Session] session
289
+ # @return [Integer] remaining time (in seconds) until offline key store expires and user is required to relogin
290
+ # @method offline_time_left(session)
32
291
  attach_function :offline_time_left, [ Session ], :int
33
- attach_function :session_user_country, [ Session ], :int
34
- attach_function :session_preferred_offline_bitrate, [ Session, :bitrate, :bool ], :error
35
- attach_function :session_set_volume_normalization, [ Session, :bool ], :error
292
+
293
+ # @note if not logged in, the function always return "ZZ".
294
+ # @param [Session] session
295
+ # @return [String] currently logged in user's country code
296
+ # @method session_user_country(session)
297
+ attach_function :session_user_country, [ Session ], CountryCode
298
+
299
+ # Set preferred bitrate for offline playback.
300
+ #
301
+ # @param [Session] session
302
+ # @param [Symbol] bitrate one of :160k, :320k, :96k
303
+ # @param [Boolean] resync true if libspotify should redownload tracks with new bitrate
304
+ # @return [Symbol] error code
305
+ # @method session_preferred_offline_bitrate(session, bitrate, resync)
306
+ attach_function :session_preferred_offline_bitrate, [ Session, :bitrate, :bool ], APIError
307
+
308
+ # Set volume normalization.
309
+ #
310
+ # @param [Session] session
311
+ # @param [Boolean] normalize true if libspotify should attempt to normalize sound volume
312
+ # @return [Symbol] error code
313
+ # @method session_set_volume_normalization(session, normalize)
314
+ attach_function :session_set_volume_normalization, [ Session, :bool ], APIError
315
+
316
+ # @see #session_set_volume_normalization
317
+ # @param [Session] session
318
+ # @return [Boolean] current volume normalization setting
319
+ # @method session_get_volume_normalization(session)
36
320
  attach_function :session_get_volume_normalization, [ Session ], :bool
37
- attach_function :session_flush_caches, [ Session ], :error
321
+
322
+ # Force libspotify to write all disk-stored data to disk immediately.
323
+ #
324
+ # @note libspotify does this periodically by itself, and on logout, so usually this is not needed.
325
+ # @param [Session] session
326
+ # @return [Symbol] error code
327
+ # @method session_flush_caches(session)
328
+ attach_function :session_flush_caches, [ Session ], APIError
329
+
330
+ # @note if not logged in, the function always return an empty string.
331
+ # @param [Session] session
332
+ # @return [String] canonical name for currently logged in user
333
+ # @method session_user_name(session)
38
334
  attach_function :session_user_name, [ Session ], UTF8String
39
- attach_function :session_set_private_session, [ Session, :bool ], :error
335
+
336
+ # Set if private session is enabled.
337
+ #
338
+ # This disables sharing of what the user is listening to with Spotify Social, Facebook, and LastFM.
339
+ # The private session will automatically revert back to normal state after a period of inactivity (6 hours?).
340
+ #
341
+ # @param [Session] session
342
+ # @param [Boolean] enabled true if playback should be private
343
+ # @return [Symbol] error code
344
+ # @method session_set_private_session(session, enabled)
345
+ attach_function :session_set_private_session, [ Session, :bool ], APIError
346
+
347
+ # @see #session_set_private_session
348
+ # @param [Session] session
349
+ # @return [Boolean] true if private session is enabled
350
+ # @method session_is_private_session(session)
40
351
  attach_function :session_is_private_session, [ Session ], :bool
41
- attach_function :session_set_scrobbling, [ Session, :social_provider, :scrobbling_state ], :error
42
- attach_function :session_is_scrobbling, [ Session, :social_provider, :buffer_out ], :error
43
- attach_function :session_is_scrobbling_possible, [ Session, :social_provider, :buffer_out ], :error
44
- attach_function :session_set_social_credentials, [ Session, :social_provider, UTF8String, UTF8String ], :error
352
+
353
+ # Set if scrobbling should be enabled.
354
+ #
355
+ # @note changing the global settings are currently not supported.
356
+ # @param [Session] session
357
+ # @param [Symbol] social_provider one of :spotify, :facebook, or :lastfm
358
+ # @param [Symbol] scrobbling_state one of :use_global_setting, :local_enabled, :local_disabled, :global_enabled, :global_disabled
359
+ # @return [Symbol] error code
360
+ # @method session_set_scrobbling(session, social_provider, scrobbling_state)
361
+ attach_function :session_set_scrobbling, [ Session, :social_provider, :scrobbling_state ], APIError
362
+
363
+ # Retrieve the scrobbling state.
364
+ #
365
+ # This makes it possible to find out if scrobbling is locally overrided or if global setting is used.
366
+ #
367
+ # @example
368
+ # Spotify.session_is_scrobbling(session, :spotify) # => :global_enabled
369
+ #
370
+ # @param [Session] session
371
+ # @param [Symbol] social_provider
372
+ # @return [Symbol] current scrobbling state for the social provider
373
+ # @method session_is_scrobbling(session, social_provider)
374
+ attach_function :session_is_scrobbling, [ Session, :social_provider, :buffer_out ], APIError do |session, social_provider|
375
+ with_buffer(:int) do |state_buffer|
376
+ error = sp_session_is_scrobbling(session, social_provider, state_buffer)
377
+ enum_type(:scrobbling_state)[state_buffer.read_int] if error == :ok
378
+ end
379
+ end
380
+
381
+ # Retrieve if it is possible to scrobble to the social provider.
382
+ #
383
+ # @example
384
+ #
385
+ # @note currently this setting is only relevant to the facebook provider
386
+ # @param [Session] session
387
+ # @param [Symbol] social_provider
388
+ # @return [Boolean] true if scrobbling is possible
389
+ # @method session_is_scrobbling_possible(session, social_provider)
390
+ attach_function :session_is_scrobbling_possible, [ Session, :social_provider, :buffer_out ], APIError do |session, social_provider|
391
+ with_buffer(:char) do |possible_buffer|
392
+ error = sp_session_is_scrobbling_possible(session, social_provider, possible_buffer)
393
+ possible_buffer.read_char != 0 if error == :ok
394
+ end
395
+ end
396
+
397
+ # Set the user's credentials for a social provider.
398
+ #
399
+ # @see #session_set_scrobbling
400
+ # @note currently this is only relevenat for LastFm
401
+ # @note set scrobbling state to true to force an authentication attempt, if it fails the scrobble_error callback will be invoked
402
+ # @param [Session] session
403
+ # @param [Symbol] social_provider
404
+ # @param [String] username
405
+ # @param [String] password
406
+ # @return [Symbol] error code
407
+ # @method session_set_social_credentials(session, social_provider, username, password)
408
+ attach_function :session_set_social_credentials, [ Session, :social_provider, UTF8String, UTF8String ], APIError
45
409
  end
46
410
  end