Class: Hallon::Playlist

Inherits:
Base
  • Object
show all
Extended by:
Observable::Playlist
Includes:
Linkable, Loadable
Defined in:
lib/hallon/playlist.rb

Overview

Playlists are playlists. They contain tracks and track information such as when tracks were added or by whom. They also contain some metadata such as their own name.

Defined Under Namespace

Classes: Track, Tracks

Instance Attribute Summary

Attributes inherited from Base

#pointer

Class Method Summary collapse

Instance Method Summary collapse

Methods included from Observable::Playlist

description_changed_callback, extended, image_changed_callback, initialize_callbacks, playlist_metadata_updated_callback, playlist_renamed_callback, playlist_state_changed_callback, playlist_update_in_progress_callback, subscribers_changed_callback, track_created_changed_callback, track_message_changed_callback, track_seen_changed_callback, tracks_added_callback, tracks_moved_callback, tracks_removed_callback

Methods included from Loadable

#load

Methods included from Linkable

#===, included, #to_str

Methods inherited from Base

#==, from, from_link, #is_linkable?, #session, to_link, #to_pointer, #to_s

Constructor Details

#initialize(link) ⇒ Playlist (private)

Construct a new Playlist, given a pointer.

Parameters:


128
129
130
131
132
133
134
135
# File 'lib/hallon/playlist.rb', line 128

def initialize(link)
  @pointer = to_pointer(link, Spotify::Playlist)

  subscribe_for_callbacks do |callbacks|
    Spotify.playlist_remove_callbacks(pointer, callbacks, nil)
    Spotify.playlist_add_callbacks(pointer, callbacks, nil)
  end
end

Class Method Details

.invalid_name?(name) ⇒ String, false (private)

Given a string, returns false if the string is a valid spotify playlist name. If it’s an invalid spotify playlist name, a string describing the fault is returned.

Parameters:

  • name (String)

Returns:

  • (String, false)

    description of why the name is invalid, or false if it’s valid

See Also:


113
114
115
116
117
118
119
120
121
122
123
# File 'lib/hallon/playlist.rb', line 113

def self.invalid_name?(name)
  unless name.bytesize < 256
    return "name must be shorter than 256 bytes"
  end

  unless name =~ /[^[:space:]]/
    return "name must not be blank"
  end

  return false # no error
end

Instance Method Details

Parameters:

  • autolink_tracks (Boolean)

    if you want unplayable tracks to be linked to playable tracks (if possible)


276
277
278
# File 'lib/hallon/playlist.rb', line 276

def autolink_tracks=(autolink_tracks)
  Spotify.playlist_set_autolink_tracks(pointer, !! autolink_tracks)
end

#available_offline?Boolean (private)

Returns true if playlist is available offline (fully synced)

Returns:

  • (Boolean)

    true if playlist is available offline (fully synced)


183
184
185
# File 'lib/hallon/playlist.rb', line 183

def available_offline?
  offline_status == :yes
end

#collaborative=(collaborative) ⇒ Object (private)

Parameters:

  • collaborative (Boolean)

    true to set the playlist to collaborative


148
149
150
# File 'lib/hallon/playlist.rb', line 148

def collaborative=(collaborative)
  Spotify.playlist_set_collaborative(pointer, !!collaborative)
end

#collaborative?Boolean (private)

Returns true if the playlist is collaborative

Returns:

  • (Boolean)

    true if the playlist is collaborative


143
144
145
# File 'lib/hallon/playlist.rb', line 143

def collaborative?
  Spotify.playlist_is_collaborative(pointer)
end

#descriptionString (private)

Returns:

  • (String)

235
236
237
# File 'lib/hallon/playlist.rb', line 235

def description
  Spotify.playlist_get_description(pointer)
end

Returns pointer representation of given link.

Parameters:

Returns:

  • (Spotify::Link)

    pointer representation of given link.


101
102
103
# File 'lib/hallon/playlist.rb', line 101

from_link :playlist do |pointer|
  Spotify.playlist_create(session.pointer, pointer)
end

#imageImage? (private)

Note:

this is not the mosaic image you see in the client. Spotify allows custom images on playlists for promo campaigns etc.

Returns custom image for the playlist, if one exists

Returns:

  • (Image, nil)

    custom image for the playlist, if one exists


242
243
244
245
246
247
# File 'lib/hallon/playlist.rb', line 242

def image
  buffer = FFI::Buffer.alloc_out(20)
  if Spotify.playlist_get_image(pointer, buffer)
    Image.new buffer.read_bytes(20)
  end
end

#in_ram=(in_ram) ⇒ Object (private)

Parameters:

  • in_ram (Boolean)

    true if you want to store the playlist in RAM


178
179
180
# File 'lib/hallon/playlist.rb', line 178

def in_ram=(in_ram)
  Spotify.playlist_set_in_ram(session.pointer, pointer, !! in_ram)
end

#in_ram?Boolean (private)

Returns true if the playlist is in RAM

Returns:

  • (Boolean)

    true if the playlist is in RAM


173
174
175
# File 'lib/hallon/playlist.rb', line 173

def in_ram?
  Spotify.playlist_is_in_ram(session.pointer, pointer)
end

#insert(index = size, tracks) ⇒ Playlist (private)

Add a list of tracks to the playlist starting at given position.

Parameters:

  • index (Integer) (defaults to: size)

    starting index to add tracks from (between 0..#size)

  • tracks (Track, Array<Track>)

Returns:

Raises:


301
302
303
304
305
306
307
308
309
310
# File 'lib/hallon/playlist.rb', line 301

def insert(index = size, tracks)
  tracks = Array(tracks).map(&:pointer)
  tracks_ary = FFI::MemoryPointer.new(:pointer, tracks.size)
  tracks_ary.write_array_of_pointer(tracks)

  tap do
    error = Spotify.playlist_add_tracks(pointer, tracks_ary, tracks.size, index, session.pointer)
    Error.maybe_raise(error)
  end
end

#loaded?Boolean (private)

Returns true if the playlist is loaded

Returns:

  • (Boolean)

    true if the playlist is loaded


138
139
140
# File 'lib/hallon/playlist.rb', line 138

def loaded?
  Spotify.playlist_is_loaded(pointer)
end

#move(destination, indices) ⇒ Playlist (private)

Move tracks at given indices to given index.

Parameters:

  • destination (Integer)

    index to move tracks to

  • indices (Integer, Array<Integer>)

Returns:

Raises:

  • (Error)

    if the operation failed


341
342
343
344
345
346
347
348
349
350
# File 'lib/hallon/playlist.rb', line 341

def move(destination, indices)
  indices     = Array(indices)
  indices_ary = FFI::MemoryPointer.new(:int, indices.size)
  indices_ary.write_array_of_int(indices)

  tap do
    error = Spotify.playlist_reorder_tracks(pointer, indices_ary, indices.size, destination)
    Error.maybe_raise(error)
  end
end

#nameString (private)

Returns playlist name, or an empty string if unavailable.

Returns:

  • (String)

    playlist name, or an empty string if unavailable.


213
214
215
# File 'lib/hallon/playlist.rb', line 213

def name
  Spotify.playlist_name(pointer)
end

#name=(name) ⇒ Object (private)

Note:

The name must not consist of only spaces and it must be shorter than 256 characters.

Parameters:

  • name (#to_s)

    new name for playlist

Raises:

  • (Error)

    if name could not be changed


220
221
222
223
224
225
226
# File 'lib/hallon/playlist.rb', line 220

def name=(name)
  unless error = Playlist.invalid_name?(name)
    Error.maybe_raise(Spotify.playlist_rename(pointer, name))
  else
    raise ArgumentError, error
  end
end

#offline_mode=(available_offline) ⇒ Object (private)

Parameters:

  • available_offline (Boolean)

    true if you want this playlist available offline


208
209
210
# File 'lib/hallon/playlist.rb', line 208

def offline_mode=(available_offline)
  Spotify.playlist_set_offline_mode(session.pointer, pointer, !! available_offline)
end

#offline_mode?Boolean (private)

Returns true if playlist is requested to be available offline

Returns:

  • (Boolean)

    true if playlist is requested to be available offline


198
199
200
# File 'lib/hallon/playlist.rb', line 198

def offline_mode?
  offline_status != :no
end

#offline_statusSymbol (private)

Returns one of :no, :yes, :downloading, :waiting

Returns:

  • (Symbol)

    one of :no, :yes, :downloading, :waiting


203
204
205
# File 'lib/hallon/playlist.rb', line 203

def offline_status
  Spotify.playlist_get_offline_status(session.pointer, pointer)
end

#ownerUser? (private)

Returns:


229
230
231
232
# File 'lib/hallon/playlist.rb', line 229

def owner
  user = Spotify.playlist_owner(pointer)
  User.from(user)
end

#pending?Boolean (private)

Returns true if playlist has pending changes

Returns:

  • (Boolean)

    true if playlist has pending changes


168
169
170
# File 'lib/hallon/playlist.rb', line 168

def pending?
  Spotify.playlist_has_pending_changes(pointer)
end

#remove(*indices) ⇒ Playlist (private)

Remove tracks at given indices.

Parameters:

  • indices (Integer, ...)

Returns:

Raises:

  • (Error)

    if the operation failed


317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
# File 'lib/hallon/playlist.rb', line 317

def remove(*indices)
  unless indices == indices.uniq
    raise ArgumentError, "no index may occur twice"
  end

  unless indices.all? { |i| i.between?(0, size-1) }
    raise ArgumentError, "indices must be inside #{0...size}"
  end

  indices_ary = FFI::MemoryPointer.new(:int, indices.size)
  indices_ary.write_array_of_int(indices)

  tap do
    error = Spotify.playlist_remove_tracks(pointer, indices_ary, indices.size)
    Error.maybe_raise(error)
  end
end

#sizeInteger (private)

Note:

Will be 0 unless #loaded?.

Returns number of tracks in playlist

Returns:

  • (Integer)

    number of tracks in playlist


282
283
284
# File 'lib/hallon/playlist.rb', line 282

def size
  Spotify.playlist_num_tracks(pointer)
end

#subscribersArray<String> (private)

Note:

this list might be shorter than #total_subscribers, as libspotify does not store more than 500 subscriber names

Returns list of canonical usernames

Returns:

  • (Array<String>)

    list of canonical usernames


252
253
254
255
# File 'lib/hallon/playlist.rb', line 252

def subscribers
  subscribers = Spotify.playlist_subscribers(pointer)
  subscribers.to_a
end

#sync_progressInteger (private)

Note:

only applicable if #offline_status is :downloading

Returns percentage done of playlist offline sync

Returns:

  • (Integer)

    percentage done of playlist offline sync


271
272
273
# File 'lib/hallon/playlist.rb', line 271

def sync_progress
  Spotify.playlist_get_offline_download_completed(session.pointer, pointer)
end

#syncing?Boolean (private)

Returns true if playlist is currently syncing

Returns:

  • (Boolean)

    true if playlist is currently syncing


188
189
190
# File 'lib/hallon/playlist.rb', line 188

def syncing?
  offline_status == :downloading
end

Returns Link for the current object.

Returns:


105
# File 'lib/hallon/playlist.rb', line 105

to_link :from_playlist

#total_subscribersInteger (private)

Returns total number of subscribers.

Returns:

  • (Integer)

    total number of subscribers.


258
259
260
# File 'lib/hallon/playlist.rb', line 258

def total_subscribers
  Spotify.playlist_num_subscribers(pointer)
end

#tracksTracks (private)

Returns a list of playlist tracks.

Examples:

retrieve track at index 3

track = playlist.tracks[3]
puts track.name

Returns:

  • (Tracks)

    a list of playlist tracks.


291
292
293
# File 'lib/hallon/playlist.rb', line 291

def tracks
  Tracks.new(self)
end

#update_subscribersPlaylist (private)

Ask libspotify to update subscriber information

Returns:


265
266
267
# File 'lib/hallon/playlist.rb', line 265

def update_subscribers
  tap { Spotify.playlist_update_subscribers(session.pointer, pointer) }
end

#upload(timeout = Hallon.load_timeout) ⇒ Playlist (private)

Note:

this is done by waiting for the libspotify callback, where libspotify tells Hallon the playlist update is done.

Waits for the playlist to begin updating and blocks until it is done.

Parameters:

  • timeout (Integer) (defaults to: Hallon.load_timeout)

    time until the operation times out

Returns:

Raises:


160
161
162
163
164
165
# File 'lib/hallon/playlist.rb', line 160

def upload(timeout = Hallon.load_timeout)
  Timeout.timeout(timeout, Hallon::TimeoutError) do
    wait_for(:playlist_update_in_progress) { |done| done }
    self
  end
end

#waiting?Boolean (private)

Returns true if playlist is queued for offline syncing

Returns:

  • (Boolean)

    true if playlist is queued for offline syncing


193
194
195
# File 'lib/hallon/playlist.rb', line 193

def waiting?
  offline_status == :waiting
end