spotify 12.5.3 → 12.6.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.gitignore +2 -0
- data/.travis.yml +20 -5
- data/CHANGELOG.md +29 -1
- data/Gemfile +5 -0
- data/MIT-LICENSE +21 -0
- data/README.markdown +75 -50
- data/Rakefile +1 -1
- data/examples/example-audio_delivery_speed.rb +48 -0
- data/examples/{audio-stream_example.rb → example-audio_stream.rb} +14 -29
- data/examples/example-console.rb +9 -0
- data/examples/example-listing_playlists.rb +89 -0
- data/examples/example-loading_object.rb +25 -0
- data/examples/example-random_related_artists.rb +53 -0
- data/examples/support.rb +106 -0
- data/lib/spotify.rb +36 -55
- data/lib/spotify/api.rb +54 -26
- data/lib/spotify/api/album.rb +45 -2
- data/lib/spotify/api/album_browse.rb +81 -3
- data/lib/spotify/api/artist.rb +21 -2
- data/lib/spotify/api/artist_browse.rb +121 -3
- data/lib/spotify/api/error.rb +5 -1
- data/lib/spotify/api/image.rb +72 -6
- data/lib/spotify/api/inbox.rb +33 -4
- data/lib/spotify/api/link.rb +117 -4
- data/lib/spotify/api/miscellaneous.rb +12 -0
- data/lib/spotify/api/playlist.rb +321 -16
- data/lib/spotify/api/playlist_container.rb +168 -9
- data/lib/spotify/api/search.rb +156 -3
- data/lib/spotify/api/session.rb +390 -26
- data/lib/spotify/api/toplist_browse.rb +74 -3
- data/lib/spotify/api/track.rb +134 -4
- data/lib/spotify/api/user.rb +18 -2
- data/lib/spotify/api_helpers.rb +47 -0
- data/lib/spotify/data_converters.rb +7 -0
- data/lib/spotify/{types → data_converters}/best_effort_string.rb +1 -1
- data/lib/spotify/{types → data_converters}/byte_string.rb +0 -0
- data/lib/spotify/data_converters/country_code.rb +30 -0
- data/lib/spotify/{types → data_converters}/image_id.rb +1 -1
- data/lib/spotify/{type_safety.rb → data_converters/type_safety.rb} +0 -0
- data/lib/spotify/{types → data_converters}/utf8_string.rb +2 -2
- data/lib/spotify/{types → data_converters}/utf8_string_pointer.rb +2 -2
- data/lib/spotify/error.rb +180 -47
- data/lib/spotify/managed_pointer.rb +32 -12
- data/lib/spotify/monkey_patches/ffi_buffer.rb +11 -0
- data/lib/spotify/monkey_patches/ffi_enums.rb +4 -0
- data/lib/spotify/monkey_patches/ffi_pointer.rb +1 -0
- data/lib/spotify/structs.rb +4 -0
- data/lib/spotify/structs/session_callbacks.rb +97 -26
- data/lib/spotify/structs/session_config.rb +1 -1
- data/lib/spotify/structs/subscribers.rb +4 -3
- data/lib/spotify/types.rb +104 -5
- data/lib/spotify/{objects → types}/album.rb +0 -0
- data/lib/spotify/{objects → types}/album_browse.rb +0 -0
- data/lib/spotify/{objects → types}/artist.rb +0 -0
- data/lib/spotify/{objects → types}/artist_browse.rb +0 -0
- data/lib/spotify/{objects → types}/image.rb +0 -0
- data/lib/spotify/{objects → types}/inbox.rb +0 -0
- data/lib/spotify/{objects → types}/link.rb +0 -0
- data/lib/spotify/{objects → types}/playlist.rb +0 -0
- data/lib/spotify/{objects → types}/playlist_container.rb +0 -0
- data/lib/spotify/{objects → types}/search.rb +0 -0
- data/lib/spotify/{objects → types}/session.rb +0 -0
- data/lib/spotify/{objects → types}/toplist_browse.rb +0 -0
- data/lib/spotify/{objects → types}/track.rb +0 -0
- data/lib/spotify/{objects → types}/user.rb +0 -0
- data/lib/spotify/util.rb +38 -35
- data/lib/spotify/version.rb +1 -1
- data/spec/spec_helper.rb +24 -13
- data/spec/spotify/api/image_spec.rb +32 -0
- data/spec/spotify/api/inbox_spec.rb +34 -0
- data/spec/spotify/api/link_spec.rb +40 -0
- data/spec/spotify/api/playlist_spec.rb +99 -0
- data/spec/spotify/api/playlistcontainer_spec.rb +82 -0
- data/spec/spotify/api/session_spec.rb +97 -0
- data/spec/spotify/api/track_spec.rb +29 -0
- data/spec/spotify/api_error_spec.rb +55 -0
- data/spec/spotify/api_spec.rb +17 -11
- data/spec/spotify/{types → data_converters}/best_effort_string_spec.rb +4 -4
- data/spec/spotify/{types → data_converters}/byte_string_spec.rb +0 -0
- data/spec/spotify/data_converters/country_code_spec.rb +16 -0
- data/spec/spotify/{types → data_converters}/image_id_spec.rb +1 -1
- data/spec/spotify/{type_safety_spec.rb → data_converters/type_safety_spec.rb} +0 -0
- data/spec/spotify/{types → data_converters}/utf8_string_pointer_spec.rb +0 -0
- data/spec/spotify/{types → data_converters}/utf8_string_spec.rb +1 -1
- data/spec/spotify/{api/functions_spec.rb → functions_spec.rb} +2 -0
- data/spec/spotify/managed_pointer_spec.rb +13 -13
- data/spec/spotify/structs/subscribers_spec.rb +5 -3
- data/spec/spotify/{defines_spec.rb → types_spec.rb} +16 -3
- data/spec/spotify/util_spec.rb +24 -0
- data/spec/spotify_spec.rb +74 -0
- data/spec/support/spotify_util.rb +6 -2
- data/spec/support/spy_output.rb +16 -0
- data/spotify.gemspec +4 -2
- metadata +111 -71
- data/examples/README.md +0 -15
- data/examples/console_example.rb +0 -22
- data/examples/example_support.rb +0 -66
- data/examples/loading-object_example.rb +0 -43
- data/examples/logging-in_example.rb +0 -58
- data/lib/spotify/defines.rb +0 -109
- data/lib/spotify/objects.rb +0 -17
- data/spec/spotify/enums_spec.rb +0 -9
- data/spec/spotify/spotify_spec.rb +0 -69
@@ -0,0 +1,25 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
# encoding: utf-8
|
3
|
+
|
4
|
+
require_relative "support"
|
5
|
+
|
6
|
+
session = Support.initialize_spotify!
|
7
|
+
|
8
|
+
track_uri = Support.prompt("Please enter a track URI", "spotify:track:1612JQ4JxS8bm5ky53N3bH")
|
9
|
+
link = Spotify.link_create_from_string(track_uri)
|
10
|
+
|
11
|
+
if link.nil?
|
12
|
+
$logger.error "Invalid URI. Aborting."
|
13
|
+
abort
|
14
|
+
elsif (link_type = Spotify.link_type(link)) != :track
|
15
|
+
$logger.error "Was #{link_type} URI. Needs track. Aborting."
|
16
|
+
abort
|
17
|
+
else
|
18
|
+
track = Spotify.link_as_track(link)
|
19
|
+
end
|
20
|
+
|
21
|
+
$logger.info "Attempting to load track. Waiting forever until successful."
|
22
|
+
Support.poll(session) { Spotify.track_is_loaded(track) }
|
23
|
+
$logger.info "Track loaded."
|
24
|
+
|
25
|
+
puts Spotify.track_name(track)
|
@@ -0,0 +1,53 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
# encoding: utf-8
|
3
|
+
|
4
|
+
require_relative "support"
|
5
|
+
|
6
|
+
session = Support.initialize_spotify!
|
7
|
+
|
8
|
+
artist_uri = Support.prompt("Please enter an artist URI to start with", "spotify:artist:7sVQKNtdP2NylxMgbNOJMM")
|
9
|
+
link = Spotify.link_create_from_string(artist_uri)
|
10
|
+
|
11
|
+
if link.null?
|
12
|
+
$logger.error "Invalid URI. Aborting."
|
13
|
+
abort
|
14
|
+
elsif (link_type = Spotify.link_type(link)) != :artist
|
15
|
+
$logger.error "Was #{link_type} URI. Needs artist. Aborting."
|
16
|
+
abort
|
17
|
+
end
|
18
|
+
|
19
|
+
target = Spotify.link_as_artist(link)
|
20
|
+
|
21
|
+
# Spotify.enum & :no_tracks & :no_albums
|
22
|
+
no_tracks = Spotify::Util.enum_value!(:no_tracks, "album type")
|
23
|
+
no_albums = Spotify::Util.enum_value!(:no_albums, "album type")
|
24
|
+
$dummy_callback = proc { }
|
25
|
+
|
26
|
+
artists = Set.new
|
27
|
+
count = 0
|
28
|
+
|
29
|
+
while target
|
30
|
+
$logger.info "Stats: #{artists.length} artists, #{count} browses."
|
31
|
+
|
32
|
+
browser = Spotify.artistbrowse_create(session, target, no_tracks | no_albums, $dummy_callback, nil)
|
33
|
+
|
34
|
+
Support.poll(session) do
|
35
|
+
begin
|
36
|
+
Spotify.try(:artistbrowse_error, browser)
|
37
|
+
rescue Spotify::IsLoadingError
|
38
|
+
# Ignore it
|
39
|
+
end
|
40
|
+
|
41
|
+
Spotify.artistbrowse_is_loaded(browser)
|
42
|
+
end
|
43
|
+
|
44
|
+
similar_artists = Spotify.artistbrowse_num_similar_artists(browser).times.map do |index|
|
45
|
+
Spotify.artistbrowse_similar_artist(browser, index)
|
46
|
+
end
|
47
|
+
|
48
|
+
similar_artists_names = similar_artists.map { |artist| Spotify.artist_name(artist) }
|
49
|
+
|
50
|
+
target = similar_artists.sample
|
51
|
+
artists << Spotify.artist_name(target)
|
52
|
+
count += 1
|
53
|
+
end
|
data/examples/support.rb
ADDED
@@ -0,0 +1,106 @@
|
|
1
|
+
require "bundler/setup"
|
2
|
+
require "spotify"
|
3
|
+
require "logger"
|
4
|
+
require "pry"
|
5
|
+
require "io/console"
|
6
|
+
|
7
|
+
# Kill main thread if any other thread dies.
|
8
|
+
Thread.abort_on_exception = true
|
9
|
+
|
10
|
+
# We use a logger to print some information on when things are happening.
|
11
|
+
$stderr.sync = true
|
12
|
+
$logger = Logger.new($stderr)
|
13
|
+
$logger.level = Logger::INFO
|
14
|
+
$logger.formatter = proc do |severity, datetime, progname, msg|
|
15
|
+
progname = if progname
|
16
|
+
" (#{progname}) "
|
17
|
+
else
|
18
|
+
" "
|
19
|
+
end
|
20
|
+
"\n[#{severity} @ #{datetime.strftime("%H:%M:%S")}]#{progname}#{msg}"
|
21
|
+
end
|
22
|
+
|
23
|
+
#
|
24
|
+
# Some utility.
|
25
|
+
#
|
26
|
+
|
27
|
+
module Support
|
28
|
+
module_function
|
29
|
+
|
30
|
+
DEFAULT_CONFIG = {
|
31
|
+
api_version: Spotify::API_VERSION.to_i,
|
32
|
+
application_key: File.binread("./spotify_appkey.key"),
|
33
|
+
cache_location: ".spotify/",
|
34
|
+
settings_location: ".spotify/",
|
35
|
+
user_agent: "spotify for ruby",
|
36
|
+
callbacks: Spotify::SessionCallbacks.new
|
37
|
+
}
|
38
|
+
|
39
|
+
def logger
|
40
|
+
$logger
|
41
|
+
end
|
42
|
+
|
43
|
+
class << self
|
44
|
+
attr_accessor :silenced
|
45
|
+
end
|
46
|
+
|
47
|
+
# libspotify supports callbacks, but they are not useful for waiting on
|
48
|
+
# operations (how they fire can be strange at times, and sometimes they
|
49
|
+
# might not fire at all). As a result, polling is the way to go.
|
50
|
+
def poll(session, idle_time = 0.05)
|
51
|
+
until yield
|
52
|
+
print "." unless silenced
|
53
|
+
process_events(session)
|
54
|
+
sleep(idle_time)
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
# Process libspotify events once.
|
59
|
+
def process_events(session)
|
60
|
+
Spotify.session_process_events(session)
|
61
|
+
end
|
62
|
+
|
63
|
+
# Ask the user for input with a prompt explaining what kind of input.
|
64
|
+
def prompt(message, default = nil)
|
65
|
+
if default
|
66
|
+
print "\n#{message} [#{default}]: "
|
67
|
+
input = gets.chomp
|
68
|
+
|
69
|
+
if input.empty?
|
70
|
+
default
|
71
|
+
else
|
72
|
+
input
|
73
|
+
end
|
74
|
+
else
|
75
|
+
print "\n#{message}: "
|
76
|
+
gets.chomp
|
77
|
+
end
|
78
|
+
end
|
79
|
+
|
80
|
+
def initialize_spotify!(config = DEFAULT_CONFIG)
|
81
|
+
error, session = Spotify.session_create(config)
|
82
|
+
raise error if error.is_a?(Spotify::APIError)
|
83
|
+
|
84
|
+
if username = Spotify.session_remembered_user(session)
|
85
|
+
logger.info "Using remembered login for: #{username}."
|
86
|
+
Spotify.try(:session_relogin, session)
|
87
|
+
else
|
88
|
+
username = prompt("Spotify username, or Facebook e-mail")
|
89
|
+
password = $stdin.noecho { prompt("Spotify password, or Facebook password") }
|
90
|
+
|
91
|
+
logger.info "Attempting login with #{username}."
|
92
|
+
Spotify.try(:session_login, session, username, password, true, nil)
|
93
|
+
end
|
94
|
+
|
95
|
+
logger.info "Log in requested. Waiting forever until logged in."
|
96
|
+
Support.poll(session) { Spotify.session_connectionstate(session) == :logged_in }
|
97
|
+
|
98
|
+
at_exit do
|
99
|
+
logger.info "Logging out."
|
100
|
+
Spotify.session_logout(session)
|
101
|
+
Support.poll(session) { Spotify.session_connectionstate(session) != :logged_in }
|
102
|
+
end
|
103
|
+
|
104
|
+
session
|
105
|
+
end
|
106
|
+
end
|
data/lib/spotify.rb
CHANGED
@@ -1,8 +1,15 @@
|
|
1
1
|
# encoding: utf-8
|
2
2
|
require 'ffi'
|
3
3
|
require 'spotify/monkey_patches/ffi_pointer'
|
4
|
+
require 'spotify/monkey_patches/ffi_buffer'
|
5
|
+
require 'spotify/monkey_patches/ffi_enums'
|
6
|
+
|
4
7
|
require 'libspotify'
|
5
|
-
require '
|
8
|
+
require 'performer'
|
9
|
+
|
10
|
+
require 'spotify/version'
|
11
|
+
require 'spotify/util'
|
12
|
+
require 'spotify/api'
|
6
13
|
|
7
14
|
# Spotify module allows you to place calls against the Spotify::API.
|
8
15
|
#
|
@@ -10,61 +17,38 @@ require 'monitor'
|
|
10
17
|
# @see Spotify::API Spotify::API on available libspotify methods
|
11
18
|
# @see http://developer.spotify.com/en/libspotify/docs/ official libspotify documentation
|
12
19
|
module Spotify
|
13
|
-
#
|
14
|
-
|
15
|
-
# All functions are attached as both instance methods and class methods, mainly
|
16
|
-
# because that’s how FFI works it’s magic with attach_function. However, as this
|
17
|
-
# is a class it allows to be instantiated.
|
18
|
-
#
|
19
|
-
# @note The API is private because this class is an implementation detail.
|
20
|
-
#
|
21
|
-
# @note You should never call any Spotify::API.method() directly, but instead
|
22
|
-
# you should call them via Spotify.method(). libspotify is not thread-safe,
|
23
|
-
# but it is documented to be okay to call the API from multiple threads *if*
|
24
|
-
# you only call one function at a time, which is ensured by the lock in the
|
25
|
-
# Spotify module.
|
26
|
-
#
|
27
|
-
# @api private
|
28
|
-
class API
|
29
|
-
extend FFI::Library
|
30
|
-
|
31
|
-
begin
|
32
|
-
ffi_lib [LIBSPOTIFY_BIN, 'spotify', 'libspotify', '/Library/Frameworks/libspotify.framework/libspotify']
|
33
|
-
ffi_convention :stdcall if FFI::Platform.windows?
|
34
|
-
rescue LoadError
|
35
|
-
puts <<-ERROR.gsub(/^ */, '')
|
36
|
-
Failed to load the `libspotify` library. It is possible that the libspotify gem
|
37
|
-
does not exist for your platform, in which case you’ll need to install it manually.
|
20
|
+
# @return [String] libspotify build ID.
|
21
|
+
API_BUILD = Spotify::API.build_id
|
38
22
|
|
39
|
-
|
40
|
-
|
41
|
-
ERROR
|
42
|
-
raise
|
43
|
-
end
|
23
|
+
unless API_BUILD.include?(Spotify::API_VERSION)
|
24
|
+
warn "[WARNING:#{__FILE__}] libspotify v#{build_id} might be incompatible with ruby spotify v#{VERSION}(#{API_VERSION})"
|
44
25
|
end
|
45
26
|
|
27
|
+
@performer = Performer.new
|
46
28
|
@__api__ = Spotify::API
|
47
|
-
@__api__.extend(MonitorMixin)
|
48
29
|
|
49
30
|
class << self
|
31
|
+
# @see https://rubygems.org/gems/performer
|
32
|
+
# @return [Performer]
|
33
|
+
attr_reader :performer
|
34
|
+
|
50
35
|
# Like send, but raises an error if the method returns a non-OK error.
|
51
36
|
#
|
52
37
|
# @example calling a method that returns an error
|
53
38
|
# Spotify.relogin(session) # => :invalid_indata
|
54
|
-
# Spotify.try(:relogin, session) # => raises
|
39
|
+
# Spotify.try(:relogin, session) # => raises APIError
|
55
40
|
#
|
56
41
|
# @note Works for non-error returning methods as well, it just does
|
57
42
|
# not do anything interesting.
|
58
43
|
#
|
59
44
|
# @param [#to_s] name
|
60
45
|
# @param args
|
61
|
-
# @raise [
|
46
|
+
# @raise [APIError] if an error other than :ok is returned
|
62
47
|
def try(name, *args, &block)
|
63
48
|
public_send(name, *args, &block).tap do |error|
|
64
|
-
error
|
65
|
-
|
66
|
-
|
67
|
-
raise Error.new(symbol)
|
49
|
+
if error.is_a?(APIError)
|
50
|
+
raise error unless error.is_a?(IsLoadingError)
|
51
|
+
end
|
68
52
|
end
|
69
53
|
end
|
70
54
|
|
@@ -80,9 +64,7 @@ module Spotify
|
|
80
64
|
# @param [Boolean] include_private
|
81
65
|
# @return [Boolean] true if the API supports the given method.
|
82
66
|
def respond_to_missing?(name, include_private = false)
|
83
|
-
@__api__.
|
84
|
-
@__api__.respond_to?(name, include_private)
|
85
|
-
end
|
67
|
+
@__api__.respond_to?(name, include_private)
|
86
68
|
end
|
87
69
|
|
88
70
|
# Calls the any method on the underlying {Spotify::API}.
|
@@ -90,25 +72,24 @@ module Spotify
|
|
90
72
|
# @example calling the API
|
91
73
|
# Spotify.link_create_from_string("spotify:user:burgestrand") # => #<Spotify::Link address=0x0deadbeef>
|
92
74
|
#
|
93
|
-
# @note Spotify protects all calls to {Spotify::API}
|
94
|
-
#
|
95
|
-
# is re-entrant.
|
75
|
+
# @note Spotify protects all calls to {Spotify::API} by calling all
|
76
|
+
# API methods in the {.performer} thread.
|
96
77
|
#
|
97
78
|
# @param [Symbol, String] name
|
98
79
|
# @param [Object, …] args
|
99
80
|
def method_missing(name, *args, &block)
|
100
|
-
|
101
|
-
@__api__.
|
81
|
+
if respond_to?(name)
|
82
|
+
performer.sync { @__api__.public_send(name, *args, &block) }
|
83
|
+
else
|
84
|
+
super
|
102
85
|
end
|
103
86
|
end
|
87
|
+
|
88
|
+
# Print debug messages, if $DEBUG is true.
|
89
|
+
#
|
90
|
+
# @param [String] message
|
91
|
+
def log(message)
|
92
|
+
$stdout.puts "[#{caller[0]}] #{message}" if $DEBUG
|
93
|
+
end
|
104
94
|
end
|
105
95
|
end
|
106
|
-
|
107
|
-
require 'spotify/version'
|
108
|
-
require 'spotify/util'
|
109
|
-
require 'spotify/types'
|
110
|
-
require 'spotify/error'
|
111
|
-
require 'spotify/objects'
|
112
|
-
require 'spotify/defines'
|
113
|
-
require 'spotify/structs'
|
114
|
-
require 'spotify/api'
|
data/lib/spotify/api.rb
CHANGED
@@ -1,49 +1,77 @@
|
|
1
1
|
module Spotify
|
2
|
+
# API is the class which has all libspotify functions attached.
|
3
|
+
#
|
4
|
+
# All functions are attached as both instance methods and class methods, mainly
|
5
|
+
# because that’s how FFI works it’s magic with attach_function. However, as this
|
6
|
+
# is a class it allows to be instantiated.
|
7
|
+
#
|
8
|
+
# @note The API is private because this class is an implementation detail.
|
9
|
+
#
|
10
|
+
# @note You should never call any Spotify::API.method() directly, but instead
|
11
|
+
# you should call them via Spotify.method(). libspotify is not thread-safe,
|
12
|
+
# but it is documented to be okay to call the API from multiple threads *if*
|
13
|
+
# you only call one function at a time, which is ensured by the lock in the
|
14
|
+
# Spotify module.
|
15
|
+
#
|
16
|
+
# @api private
|
2
17
|
class API
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
18
|
+
extend FFI::Library
|
19
|
+
|
20
|
+
begin
|
21
|
+
ffi_lib [LIBSPOTIFY_BIN, 'spotify', 'libspotify', '/Library/Frameworks/libspotify.framework/libspotify']
|
22
|
+
ffi_convention :stdcall if FFI::Platform.windows?
|
23
|
+
rescue LoadError
|
24
|
+
$stderr.puts <<-ERROR.gsub(/^ */, '')
|
25
|
+
Failed to load the `libspotify` library. It is possible that the libspotify gem
|
26
|
+
does not exist for your platform, in which case you'll need to install it manually.
|
27
|
+
|
28
|
+
For manual installation instructions, please see:
|
29
|
+
https://github.com/Burgestrand/Hallon/wiki/How-to-install-libspotify
|
30
|
+
ERROR
|
31
|
+
raise
|
32
|
+
end
|
33
|
+
|
11
34
|
# Overloaded to ensure all methods are defined as blocking,
|
12
35
|
# and they return a managed pointer with the correct refcount.
|
13
36
|
#
|
14
37
|
# @param [#to_s] name function name sans `sp_` prefix.
|
15
38
|
# @param [Array] args
|
16
39
|
# @param [Object] returns
|
17
|
-
def self.attach_function(c_name = nil, name, args, returns)
|
40
|
+
def self.attach_function(c_name = nil, name, args, returns, &block)
|
18
41
|
if returns.respond_to?(:retaining_class) && name !~ /create/
|
19
42
|
returns = returns.retaining_class
|
20
43
|
end
|
21
44
|
|
22
|
-
options = { :
|
23
|
-
|
45
|
+
options = { blocking: true }
|
46
|
+
name = name.to_sym
|
47
|
+
c_name ||= :"sp_#{name}"
|
24
48
|
super(name, c_name, args, returns, options)
|
25
|
-
end
|
26
49
|
|
27
|
-
|
50
|
+
if block_given?
|
51
|
+
alias_method c_name, name
|
52
|
+
define_method name, &block
|
28
53
|
|
29
|
-
|
54
|
+
singleton_class.instance_eval do
|
55
|
+
alias_method c_name, name
|
56
|
+
define_method name, &block
|
57
|
+
end
|
30
58
|
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
# @!endgroup
|
35
|
-
end
|
36
|
-
|
37
|
-
# @return [String] libspotify build ID.
|
38
|
-
API_BUILD = Spotify.build_id
|
59
|
+
name
|
60
|
+
end
|
61
|
+
end
|
39
62
|
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
raise LoadError, "libspotify v#{build_id} is incompatible with ruby spotify v#{VERSION}(#{API_VERSION})"
|
63
|
+
require "spotify/api_helpers"
|
64
|
+
extend APIHelpers
|
65
|
+
include APIHelpers
|
44
66
|
end
|
45
67
|
end
|
46
68
|
|
69
|
+
require 'spotify/error'
|
70
|
+
require 'spotify/data_converters'
|
71
|
+
require 'spotify/types'
|
72
|
+
require 'spotify/structs'
|
73
|
+
|
74
|
+
require 'spotify/api/miscellaneous'
|
47
75
|
require 'spotify/api/album'
|
48
76
|
require 'spotify/api/album_browse'
|
49
77
|
require 'spotify/api/artist'
|
data/lib/spotify/api/album.rb
CHANGED
@@ -1,14 +1,57 @@
|
|
1
1
|
module Spotify
|
2
2
|
class API
|
3
3
|
# @!group Album
|
4
|
+
|
5
|
+
# @param [Album] album
|
6
|
+
# @return [Boolean] true if the album is populated with data
|
7
|
+
# @method album_is_loaded(album)
|
4
8
|
attach_function :album_is_loaded, [ Album ], :bool
|
9
|
+
|
10
|
+
# @see #album_is_loaded
|
11
|
+
# @note the album must be loaded, or this function always return false.
|
12
|
+
# @param [Album] album
|
13
|
+
# @return [Boolean] true if the album is available for playback
|
14
|
+
# @method album_is_available(album)
|
5
15
|
attach_function :album_is_available, [ Album ], :bool
|
16
|
+
|
17
|
+
# @see #album_is_loaded
|
18
|
+
# @note the album must be loaded, or this function always return nil.
|
19
|
+
# @param [Album] album
|
20
|
+
# @return [Artist, nil] authoring artist of the album
|
21
|
+
# @method album_artist(album)
|
6
22
|
attach_function :album_artist, [ Album ], Artist
|
23
|
+
|
24
|
+
# @see #image_create
|
25
|
+
# @see #album_is_loaded
|
26
|
+
# @note the album must be loaded, or this function always return nil.
|
27
|
+
# @param [Album] album
|
28
|
+
# @param [Symbol] image_size one of :normal, :small, :large
|
29
|
+
# @return [String, nil] image ID to pass to {#image_create}, or nil if the album has no image
|
30
|
+
# @method album_cover(album, image_size)
|
7
31
|
attach_function :album_cover, [ Album, :image_size ], ImageID
|
32
|
+
|
33
|
+
# @see #album_is_loaded
|
34
|
+
# @note the album must be loaded, or this function always return an empty string.
|
35
|
+
# @param [Album] album
|
36
|
+
# @return [String] name of the album
|
37
|
+
# @method album_name(album)
|
8
38
|
attach_function :album_name, [ Album ], UTF8String
|
39
|
+
|
40
|
+
# @see #album_is_loaded
|
41
|
+
# @note the album must be loaded, or this function always return 0.
|
42
|
+
# @param [Album] album
|
43
|
+
# @return [String] release year of the album
|
44
|
+
# @method album_year(album)
|
9
45
|
attach_function :album_year, [ Album ], :int
|
46
|
+
|
47
|
+
# @see #album_is_loaded
|
48
|
+
# @note the album must be loaded, or this function always return :unknown.
|
49
|
+
# @param [Album] album
|
50
|
+
# @return [Symbol] album type, one of :album, :single, :compilation, :unknown
|
51
|
+
# @method album_type(album)
|
10
52
|
attach_function :album_type, [ Album ], :albumtype
|
11
|
-
|
12
|
-
attach_function :
|
53
|
+
|
54
|
+
attach_function :album_add_ref, [ Album ], APIError
|
55
|
+
attach_function :album_release, [ Album ], APIError
|
13
56
|
end
|
14
57
|
end
|