lib/spotify/api/playlist_container.rb
module Spotify
class API
# @!group PlaylistContainer
# Attach callbacks to the container, used for getting change notifications.
#
# @example
# callbacks = Spotify::PlaylistContainerCallbacks.new({
# container_loaded: proc { |playlist| puts "Container loaded!" },
# })
# Spotify.playlistcontainer_add_callbacks(container, callbacks, nil) # => :ok
#
# @note it is *very* important that the callbacks are not garbage collected before they are called!
# @param [PlaylistContainer] container
# @param [PlaylistContainerCallbacks] container_callbacks
# @param [FFI::Pointer] userdata
# @return [Symbol] error code
# @method playlistcontainer_add_callbacks(container, container_callbacks, userdata)
attach_function :playlistcontainer_add_callbacks, [ PlaylistContainer, PlaylistContainerCallbacks.by_ref, :userdata ], APIError
# Remove container callbacks previously added with {#playlistcontainer_add_callbacks}.
#
# @see #playlistcontainer_add_callbacks
# @param [PlaylistContainer] container
# @param [PlaylistCallbacks] container_callbacks
# @param [FFI::Pointer] userdata
# @return [Symbol] error code
# @method playlistcontainer_remove_callbacks(container, container_callbacks, userdata)
attach_function :playlistcontainer_remove_callbacks, [ PlaylistContainer, PlaylistContainerCallbacks.by_ref, :userdata ], APIError
# @see #playlistcontainer_is_loaded
# @see #playlistcontainer_playlist
# @note if the container is not loaded, the function will always return 0.
# @param [PlaylistContainer] container
# @return [Integer] number of playlists in container
# @method playlistcontainer_num_playlists(container)
attach_function :playlistcontainer_num_playlists, [ PlaylistContainer ], :int
# @see #playlistcontainer_num_playlists
# @note if index is out of range, the function always return nil.
# @param [PlaylistContainer] container
# @param [Integer] index number between 0...{#playlistcontainer_num_playlists}
# @return [Playlist, nil] playlist at index
# @method playlistcontainer_playlist(container)
attach_function :playlistcontainer_playlist, [ PlaylistContainer, :int ], Playlist
# @see #playlistcontainer_num_playlists
# @note if index is out of range, the function always return :playlist.
# @param [PlaylistContainer] container
# @param [Integer] index number between 0...{#playlistcontainer_num_playlists}
# @return [Symbol] playlist type of playlist at index, one of :playlist, :start_folder, :end_folder, :placeholder
# @method playlistcontainer_playlist_type(container, index)
attach_function :playlistcontainer_playlist_type, [ PlaylistContainer, :int ], :playlist_type
# Retrieve folder name of a folder in a container.
#
# @example
# Spotify.playlistcontainer_playlist_folder_name(container, index = 0) # => "Summer Playlists"
#
# @see #playlistcontainer_num_playlists
#
# @note the spotify client appear to constrain the name to 255 chars, so this function does too.
# @note if index is out of range, the function always return nil.
#
# @param [PlaylistContainer] container
# @param [Integer] index number between 0...{#playlistcontainer_num_playlists}
# @return [String, nil] name of the folder as a string, or nil if not a folder, or out of range
# @method playlistcontainer_playlist_folder_name(container, index)
attach_function :playlistcontainer_playlist_folder_name, [ PlaylistContainer, :int, :buffer_out, :int ], APIError do |container, index|
folder_name = with_string_buffer(255) do |folder_name_buffer, size|
sp_playlistcontainer_playlist_folder_name(container, index, folder_name_buffer, size)
end
folder_name unless folder_name.empty?
end
# @note if the index is out of range, the function always return 0.
# @param [PlaylistContainer] container
# @param [Integer] index number between 0...{#playlistcontainer_num_playlists}
# @return [Integer] folder id at index
# @method playlistcontainer_playlist_folder_id(container, index)
attach_function :playlistcontainer_playlist_folder_id, [ PlaylistContainer, :int ], :uint64
# Add a new playlist to the end of the container.
#
# @note the name must not constist of only spaces, and it must be shorter than 256 bytes.
# @param [PlaylistContainer] container
# @param [String] playlist_name name of the playlist
# @return [Playlist, nil] the new playlist, or nil if creation failed
# @method playlistcontainer_add_new_playlist(container, playlist_name)
attach_function :playlistcontainer_add_new_playlist, [ PlaylistContainer, UTF8String ], Playlist
# Add an existing playlist to the end of the container.
#
# @param [PlaylistContainer] container
# @param [Link] link link to a playlist
# @return [Playlist, nil] the playlist, or nil if the playlist already exists, or if the link was not a valid playlist link
# @method playlistcontainer_add_playlist(container, link)
attach_function :playlistcontainer_add_playlist, [ PlaylistContainer, Link ], Playlist
# Remove a playlist from a container.
#
# @note if you remove a folder marker, remove the other corresponding (start or stop) marker
# as well, or the playlist will be left in an inconsistent state.
#
# @note if the index is out of range, the function always return an error.
# @param [PlaylistContainer] container
# @param [Integer] index number between 0...{#playlistcontainer_num_playlists}
# @return [Symbol] error code
# @method playlistcontainer_remove_playlist(container, index)
attach_function :playlistcontainer_remove_playlist, [ PlaylistContainer, :int ], APIError
# Move a playlist to another position in the container.
#
# @note if the index is out of range, the function always return an error.
# @param [PlaylistContainer] container
# @param [Integer] index number between 0...{#playlistcontainer_num_playlists}
# @param [Integer] new_position
# @param [Boolean] dry_run do not move the playlist, only check if it is possible
# @return [Symbol] error code
# @method playlistcontainer_move_playlist(container, index, new_position, dry_run)
attach_function :playlistcontainer_move_playlist, [ PlaylistContainer, :int, :int, :bool ], APIError
# Create a new folder in the container.
#
# This creates a start_folder marker, and an end_folder marker right after it, at
# specified index.
#
# @note you cannot rename folders, if you want to do so you have to destroy the folder and recreate it
# @param [PlaylistContainer] container
# @param [Integer] index number between 0..{#playlistcontainer_num_playlists}
# @param [String] folder_name
# @method playlistcontainer_add_folder(container, index, folder_name)
attach_function :playlistcontainer_add_folder, [ PlaylistContainer, :int, UTF8String ], APIError
# @param [PlaylistContainer] container
# @return [User] owner of the container
# @method playlistcontainer_owner(container)
attach_function :playlistcontainer_owner, [ PlaylistContainer ], User
# @param [PlaylistContainer] container
# @return [Boolean] true if the container is loaded
# @method playlistcontainer_is_loaded(container)
attach_function :playlistcontainer_is_loaded, [ PlaylistContainer ], :bool
# Number of new tracks in playlist since {#playlistcontainer_clear_unseen_tracks} was called.
#
# @example number of unseen tracks in playlist
# Spotify.playlistcontainer_get_unseen_tracks(container, playlist) # => [#<Spotify::Track::Retaining address=0x103a36c10>…
#
# @note if the playlist is not in the container, this function always return an empty array.
#
# @param [PlaylistContainer] container
# @param [Playlist] playlist
# @return [Array<Track>] an array of unseen tracks
# @method playlistcontainer_get_unseen_tracks(container, playlist)
attach_function :playlistcontainer_get_unseen_tracks, [ PlaylistContainer, Playlist, :array, :int ], :int do |container, playlist|
count = sp_playlistcontainer_get_unseen_tracks(container, playlist, nil, 0)
tracks = with_buffer(Spotify::Track, size: count) do |tracks_buffer|
sp_playlistcontainer_get_unseen_tracks(container, playlist, tracks_buffer, count)
tracks_buffer.read_array_of_pointer(count).map do |pointer|
Spotify::Track.retaining_class.from_native(pointer, nil)
end
end
tracks || []
end
# Clear unseen tracks for a playlist on a container
#
# This will cause the next{#playlistcontainer_get_unseen_tracks} call to return 0.
#
# @param [PlaylistContainer] container
# @param [Playlist] playlist
# @return [Integer] 0 on success, and -1 on failure
# @method playlistcontainer_clear_unseen_tracks(container, playlist)
attach_function :playlistcontainer_clear_unseen_tracks, [ PlaylistContainer, Playlist ], :int
attach_function :playlistcontainer_add_ref, [ PlaylistContainer ], APIError
attach_function :playlistcontainer_release, [ PlaylistContainer ], APIError
end
end