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

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

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

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

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

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

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?

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

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

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

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

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

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

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

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

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

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

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?

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

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

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

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>

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

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

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

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

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

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

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

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