lib/spotify.rb
# encoding: utf-8
require 'ffi'
require 'spotify/monkey_patches/ffi_pointer'
require 'spotify/monkey_patches/ffi_buffer'
require 'spotify/monkey_patches/ffi_enums'
require 'libspotify'
require 'performer'
require 'spotify/version'
require 'spotify/util'
require 'spotify/api'
# Spotify module allows you to place calls against the Spotify::API.
#
# @see method_missing method_missing on calling the API
# @see Spotify::API Spotify::API on available libspotify methods
# @see http://developer.spotify.com/en/libspotify/docs/ official libspotify documentation
module Spotify
# @return [String] libspotify build ID.
API_BUILD = Spotify::API.build_id
unless API_BUILD.include?(Spotify::API_VERSION)
warn "[WARNING:#{__FILE__}] libspotify v#{API_BUILD} might be incompatible with ruby spotify v#{VERSION}(#{API_VERSION})"
end
@performer = Performer.new
@__api__ = Spotify::API
class << self
# @see https://rubygems.org/gems/performer
# @return [Performer]
attr_reader :performer
# Like send, but raises an error if the method returns a non-OK error.
#
# @example calling a method that returns an error
# Spotify.relogin(session) # => :invalid_indata
# Spotify.try(:relogin, session) # => raises APIError
#
# @note Works for non-error returning methods as well, it just does
# not do anything interesting.
#
# @param [#to_s] name
# @param args
# @raise [APIError] if an error other than :ok is returned
def try(name, *args, &block)
public_send(name, *args, &block).tap do |error|
if error.is_a?(APIError)
raise error unless error.is_a?(IsLoadingError)
end
end
end
# Asks the underlying Spotify API if it responds to `name`.
#
# @example
# Spotify.respond_to?(:error_message) # => true
#
# @example retrieving a method handle
# Spotify.metod(:error_message) # => #<Method: Spotify.error_message>
#
# @param [Symbol, String] name
# @param [Boolean] include_private
# @return [Boolean] true if the API supports the given method.
def respond_to_missing?(name, include_private = false)
@__api__.respond_to?(name, include_private)
end
# Calls the any method on the underlying {Spotify::API}.
#
# @example calling the API
# Spotify.link_create_from_string("spotify:user:burgestrand") # => #<Spotify::Link address=0x0deadbeef>
#
# @note Spotify protects all calls to {Spotify::API} by calling all
# API methods in the {.performer} thread.
#
# @param [Symbol, String] name
# @param [Object, …] args
def method_missing(name, *args, &block)
if respond_to?(name)
performer.sync { @__api__.public_send(name, *args, &block) }
else
super
end
end
# Print debug messages, if $DEBUG is true.
#
# @param [String] message
def log(message)
$stdout.puts "[#{caller[0]}] #{message}" if $DEBUG
end
end
end