hallon 0.16.0 → 0.17.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/.gitignore +2 -1
- data/.travis.yml +2 -0
- data/CHANGELOG.md +22 -1
- data/Gemfile +2 -2
- data/README.markdown +2 -2
- data/Rakefile +69 -42
- data/hallon.gemspec +1 -1
- data/lib/hallon.rb +3 -2
- data/lib/hallon/album.rb +6 -4
- data/lib/hallon/artist.rb +6 -4
- data/lib/hallon/audio_queue.rb +1 -1
- data/lib/hallon/base.rb +4 -0
- data/lib/hallon/blob.rb +6 -0
- data/lib/hallon/error.rb +10 -41
- data/lib/hallon/ext/spotify.rb +1 -146
- data/lib/hallon/image.rb +8 -0
- data/lib/hallon/linkable.rb +6 -0
- data/lib/hallon/loadable.rb +6 -0
- data/lib/hallon/observable.rb +1 -1
- data/lib/hallon/observable/playlist_container.rb +2 -2
- data/lib/hallon/observable/session.rb +34 -0
- data/lib/hallon/player.rb +7 -3
- data/lib/hallon/playlist.rb +5 -1
- data/lib/hallon/playlist_container.rb +9 -8
- data/lib/hallon/scrobbler.rb +103 -0
- data/lib/hallon/search.rb +1 -0
- data/lib/hallon/session.rb +69 -13
- data/lib/hallon/toplist.rb +1 -1
- data/lib/hallon/track.rb +2 -2
- data/lib/hallon/version.rb +1 -1
- data/spec/hallon/album_spec.rb +16 -0
- data/spec/hallon/artist_spec.rb +16 -0
- data/spec/hallon/base_spec.rb +1 -1
- data/spec/hallon/error_spec.rb +3 -3
- data/spec/hallon/hallon_spec.rb +1 -1
- data/spec/hallon/image_spec.rb +6 -0
- data/spec/hallon/observable/session_spec.rb +20 -0
- data/spec/hallon/scrobbler_spec.rb +119 -0
- data/spec/hallon/session_spec.rb +38 -4
- data/spec/hallon/spotify_spec.rb +0 -45
- data/spec/mockspotify.rb +6 -1
- data/spec/spec_helper.rb +4 -5
- metadata +59 -20
- data/spec/support/cover_me.rb +0 -7
data/lib/hallon/ext/spotify.rb
CHANGED
@@ -4,154 +4,9 @@
|
|
4
4
|
#
|
5
5
|
# @see https://github.com/Burgestrand/libspotify-ruby
|
6
6
|
module Spotify
|
7
|
-
# Fetches the associated value of an enum from a given symbol.
|
8
|
-
#
|
9
|
-
# @param [Symbol] symbol
|
10
|
-
# @param [#to_s] type
|
11
|
-
# @raise ArgumentError on failure
|
12
|
-
def self.enum_value!(symbol, type)
|
13
|
-
enum_value(symbol) or raise ArgumentError, "invalid #{type}: #{symbol}"
|
14
|
-
end
|
15
|
-
|
16
|
-
# Wraps the function `function` so that it always returns
|
17
|
-
# a Spotify::Pointer with correct refcount. Functions that
|
18
|
-
# contain the word `create` are assumed to start out with
|
19
|
-
# a refcount of `+1`.
|
20
|
-
#
|
21
|
-
# @param [#to_s] function
|
22
|
-
# @param [#to_s] return_type
|
23
|
-
# @raise [NoMethodError] if `function` is not defined
|
24
|
-
# @see Spotify::Pointer
|
25
|
-
def self.wrap_function(function, return_type)
|
26
|
-
method(function)
|
27
|
-
define_singleton_method("#{function}!") do |*args|
|
28
|
-
pointer = public_send(function, *args)
|
29
|
-
Spotify::Pointer.new(pointer, return_type, function !~ /create/)
|
30
|
-
end
|
31
|
-
end
|
32
|
-
|
33
|
-
# @macro [attach] wrap_function
|
34
|
-
# Same as {Spotify}.`$1`, but wraps result in a {Spotify::Pointer}.
|
35
|
-
#
|
36
|
-
# @method $1!
|
37
|
-
# @return [Spotify::Pointer<$2>]
|
38
|
-
# @see #$1
|
39
|
-
wrap_function :session_user, :user
|
40
|
-
wrap_function :session_playlistcontainer, :playlistcontainer
|
41
|
-
wrap_function :session_inbox_create, :playlist
|
42
|
-
wrap_function :session_starred_create, :playlist
|
43
|
-
wrap_function :session_starred_for_user_create, :playlist
|
44
|
-
wrap_function :session_publishedcontainer_for_user_create, :playlistcontainer
|
45
|
-
|
46
|
-
wrap_function :track_artist, :artist
|
47
|
-
wrap_function :track_album, :album
|
48
|
-
wrap_function :localtrack_create, :track
|
49
|
-
wrap_function :track_get_playable, :track
|
50
|
-
|
51
|
-
wrap_function :album_artist, :artist
|
52
|
-
|
53
|
-
wrap_function :albumbrowse_create, :albumbrowse
|
54
|
-
wrap_function :albumbrowse_album, :album
|
55
|
-
wrap_function :albumbrowse_artist, :artist
|
56
|
-
wrap_function :albumbrowse_track, :track
|
57
|
-
|
58
|
-
wrap_function :artistbrowse_create, :artistbrowse
|
59
|
-
wrap_function :artistbrowse_artist, :artist
|
60
|
-
wrap_function :artistbrowse_track, :track
|
61
|
-
wrap_function :artistbrowse_album, :album
|
62
|
-
wrap_function :artistbrowse_similar_artist, :artist
|
63
|
-
wrap_function :artistbrowse_tophit_track, :track
|
64
|
-
|
65
|
-
wrap_function :image_create, :image
|
66
|
-
wrap_function :image_create_from_link, :image
|
67
|
-
|
68
|
-
wrap_function :link_as_track, :track
|
69
|
-
wrap_function :link_as_track_and_offset, :track
|
70
|
-
wrap_function :link_as_album, :album
|
71
|
-
wrap_function :link_as_artist, :artist
|
72
|
-
wrap_function :link_as_user, :user
|
73
|
-
|
74
|
-
wrap_function :link_create_from_string, :link
|
75
|
-
wrap_function :link_create_from_track, :link
|
76
|
-
wrap_function :link_create_from_album, :link
|
77
|
-
wrap_function :link_create_from_artist, :link
|
78
|
-
wrap_function :link_create_from_search, :link
|
79
|
-
wrap_function :link_create_from_playlist, :link
|
80
|
-
wrap_function :link_create_from_artist_portrait, :link
|
81
|
-
wrap_function :link_create_from_artistbrowse_portrait, :link
|
82
|
-
wrap_function :link_create_from_album_cover, :link
|
83
|
-
wrap_function :link_create_from_image, :link
|
84
|
-
wrap_function :link_create_from_user, :link
|
85
|
-
|
86
|
-
wrap_function :search_create, :search
|
87
|
-
wrap_function :search_track, :track
|
88
|
-
wrap_function :search_album, :album
|
89
|
-
wrap_function :search_artist, :artist
|
90
|
-
|
91
|
-
wrap_function :playlist_track, :track
|
92
|
-
wrap_function :playlist_track_creator, :user
|
93
|
-
wrap_function :playlist_owner, :user
|
94
|
-
wrap_function :playlist_create, :playlist
|
95
|
-
|
96
|
-
wrap_function :playlistcontainer_playlist, :playlist
|
97
|
-
wrap_function :playlistcontainer_add_new_playlist, :playlist
|
98
|
-
wrap_function :playlistcontainer_add_playlist, :playlist
|
99
|
-
wrap_function :playlistcontainer_owner, :user
|
100
|
-
|
101
|
-
wrap_function :toplistbrowse_create, :toplistbrowse
|
102
|
-
wrap_function :toplistbrowse_artist, :artist
|
103
|
-
wrap_function :toplistbrowse_album, :album
|
104
|
-
wrap_function :toplistbrowse_track, :track
|
105
|
-
|
106
|
-
wrap_function :inbox_post_tracks, :inbox
|
107
|
-
|
108
|
-
# The Pointer is a kind of AutoPointer specially tailored for Spotify
|
109
|
-
# objects, that releases the raw pointer on GC.
|
110
|
-
class Pointer < FFI::AutoPointer
|
111
|
-
attr_reader :type
|
112
|
-
|
113
|
-
# @param [FFI::Pointer] pointer
|
114
|
-
# @param [#to_s] type session, link, etc
|
115
|
-
# @param [Boolean] add_ref
|
116
|
-
# @return [FFI::AutoPointer]
|
117
|
-
def initialize(pointer, type, add_ref)
|
118
|
-
super pointer, self.class.releaser_for(@type = type.to_s)
|
119
|
-
|
120
|
-
unless pointer.null?
|
121
|
-
Spotify.send(:"#{type}_add_ref", pointer)
|
122
|
-
end if add_ref
|
123
|
-
end
|
124
|
-
|
125
|
-
# @return [String] representation of the spotify pointer
|
126
|
-
def to_s
|
127
|
-
"<#{self.class} address=0x#{address.to_s(16)} type=#{type}>"
|
128
|
-
end
|
129
|
-
|
130
|
-
# Create a proc that will accept a pointer of a given type and
|
131
|
-
# release it with the correct function if it’s not null.
|
132
|
-
#
|
133
|
-
# @param [Symbol]
|
134
|
-
# @return [Proc]
|
135
|
-
def self.releaser_for(type)
|
136
|
-
lambda do |pointer|
|
137
|
-
unless pointer.null?
|
138
|
-
$stdout.puts "Spotify::#{type}_release(#{pointer})" if $DEBUG
|
139
|
-
Spotify.send(:"#{type}_release", pointer)
|
140
|
-
end
|
141
|
-
end
|
142
|
-
end
|
143
|
-
|
144
|
-
# @param [Object] pointer
|
145
|
-
# @param [Symbol] type (optional, no type checking is done if not given)
|
146
|
-
# @return [Boolean] true if object is a spotify pointer and of correct type
|
147
|
-
def self.typechecks?(object, type)
|
148
|
-
!! (object.type == type.to_s) if object.is_a?(Spotify::Pointer)
|
149
|
-
end
|
150
|
-
end
|
151
|
-
|
152
7
|
# Extensions to SessionConfig, allowing more sensible configuration names.
|
153
8
|
SessionConfig.class_eval do
|
154
|
-
[:cache_location, :settings_location, :user_agent, :device_id, :tracefile].each do |field|
|
9
|
+
[:cache_location, :settings_location, :user_agent, :device_id, :proxy, :proxy_username, :proxy_password, :tracefile].each do |field|
|
155
10
|
method = field.to_s.gsub('location', 'path')
|
156
11
|
|
157
12
|
define_method(:"#{method}") { self[field].read_string }
|
data/lib/hallon/image.rb
CHANGED
@@ -15,6 +15,14 @@ module Hallon
|
|
15
15
|
extend Observable::Image
|
16
16
|
include Loadable
|
17
17
|
|
18
|
+
# A list of available image sizes.
|
19
|
+
#
|
20
|
+
# @see Album#cover
|
21
|
+
# @see Artist#portrait
|
22
|
+
def self.sizes
|
23
|
+
Spotify.enum_type(:image_size).symbols
|
24
|
+
end
|
25
|
+
|
18
26
|
# Create a new instance of an Image.
|
19
27
|
#
|
20
28
|
# @example from a link
|
data/lib/hallon/linkable.rb
CHANGED
@@ -8,6 +8,9 @@ module Hallon
|
|
8
8
|
#
|
9
9
|
# @private
|
10
10
|
module Linkable
|
11
|
+
# ClassMethods adds `#from_link` and `#to_link` DSL methods, which
|
12
|
+
# essentially are convenience methods for defining the way to convert
|
13
|
+
# a link to a pointer of a given Spotify object type.
|
11
14
|
module ClassMethods
|
12
15
|
# Defines `#from_link`, used in converting a link to a pointer. You
|
13
16
|
# can either pass it a `method_name`, or a `type` and a block.
|
@@ -100,6 +103,9 @@ module Hallon
|
|
100
103
|
end
|
101
104
|
end
|
102
105
|
|
106
|
+
# Will extend `other` with ClassMethods on inclusion.
|
107
|
+
#
|
108
|
+
# @param [#extend] other
|
103
109
|
def self.included(other)
|
104
110
|
other.extend ClassMethods
|
105
111
|
end
|
data/lib/hallon/loadable.rb
CHANGED
@@ -2,7 +2,13 @@
|
|
2
2
|
require 'timeout'
|
3
3
|
|
4
4
|
module Hallon
|
5
|
+
# Extends Hallon objects with a method that allows synchronous loading of objects.
|
5
6
|
module Loadable
|
7
|
+
# Wait until the object has loaded.
|
8
|
+
#
|
9
|
+
# @example waiting for a track to load
|
10
|
+
# track = Hallon::Track.new(track_uri).load
|
11
|
+
#
|
6
12
|
# @param [Numeric] timeout after this time, if the object is not loaded, an error is raised.
|
7
13
|
# @return [self]
|
8
14
|
# @raise [Hallon::TimeoutError] after `timeout` seconds if the object does not load.
|
data/lib/hallon/observable.rb
CHANGED
@@ -115,7 +115,7 @@ module Hallon
|
|
115
115
|
#
|
116
116
|
# @note Given block will be called once instantly without parameters.
|
117
117
|
# @note If no events happen for 0.25 seconds, the block will be called without parameters.
|
118
|
-
# @param [Symbol, ...]
|
118
|
+
# @param [Symbol, ...] events list of events to wait for
|
119
119
|
# @yield [Symbol, *args] name of the event that fired, and its’ arguments
|
120
120
|
# @return whatever the block returns
|
121
121
|
def wait_for(*events)
|
@@ -72,8 +72,8 @@ module Hallon::Observable
|
|
72
72
|
|
73
73
|
# @param [Spotify::Pointer] playlist
|
74
74
|
# @return [Hallon::Playlist] a playlist for the given pointer.
|
75
|
-
def playlist_from(
|
76
|
-
pointer = Spotify::Pointer.new(
|
75
|
+
def playlist_from(playlist)
|
76
|
+
pointer = Spotify::Pointer.new(playlist, :playlist, true)
|
77
77
|
Hallon::Playlist.new(pointer)
|
78
78
|
end
|
79
79
|
end
|
@@ -249,5 +249,39 @@ module Hallon::Observable
|
|
249
249
|
def credentials_blob_updated_callback(pointer, credentials)
|
250
250
|
trigger(pointer, :credentials_blob_updated, credentials)
|
251
251
|
end
|
252
|
+
|
253
|
+
# @example listening to this event
|
254
|
+
# session.on(:connectionstate_updated) do
|
255
|
+
# puts "Yay! Connection state changed… hooray… wee… no?"
|
256
|
+
# end
|
257
|
+
#
|
258
|
+
# @yield
|
259
|
+
def connectionstate_updated_callback(pointer)
|
260
|
+
trigger(pointer, :connectionstate_updated)
|
261
|
+
end
|
262
|
+
|
263
|
+
# @example listening to this event
|
264
|
+
# session.on(:scrobble_error) do |error|
|
265
|
+
# Hallon::Error.maybe_raise(error)
|
266
|
+
# end
|
267
|
+
#
|
268
|
+
# @yield
|
269
|
+
def scrobble_error_callback(pointer, error)
|
270
|
+
trigger(pointer, :scrobble_error, error)
|
271
|
+
end
|
272
|
+
|
273
|
+
# @example listening to this event
|
274
|
+
# session.on(:private_session_mode_changed) do |enabled|
|
275
|
+
# if enabled
|
276
|
+
# puts "Private session enabled!"
|
277
|
+
# else
|
278
|
+
# puts "Private session disabled!"
|
279
|
+
# end
|
280
|
+
# end
|
281
|
+
#
|
282
|
+
# @yield
|
283
|
+
def private_session_mode_changed_callback(pointer, enabled)
|
284
|
+
trigger(pointer, :private_session_mode_changed, enabled)
|
285
|
+
end
|
252
286
|
end
|
253
287
|
end
|
data/lib/hallon/player.rb
CHANGED
@@ -122,7 +122,7 @@ module Hallon
|
|
122
122
|
# well as allow audio data to stream through the feeder
|
123
123
|
# thread.
|
124
124
|
#
|
125
|
-
# @param [Symbol]
|
125
|
+
# @param [Symbol] new_status one of :playing, :paused, :stopped
|
126
126
|
# @raise [ArgumentError] if given an invalid status
|
127
127
|
def status=(new_status)
|
128
128
|
@queue.synchronize do
|
@@ -201,10 +201,14 @@ module Hallon
|
|
201
201
|
|
202
202
|
# Set preferred playback bitrate.
|
203
203
|
#
|
204
|
+
# @note the double possible errors is a result of the same thing as for
|
205
|
+
# {Session#offline_bitrate=}, see its documentation for further information.
|
206
|
+
#
|
207
|
+
# @raise [ArgumentError] if given invalid bitrate
|
208
|
+
# @raise [Spotify::Error] if libspotify does not accept the given bitrate
|
204
209
|
# @param [Symbol] bitrate one of :96k, :160k, :320k
|
205
|
-
# @return [Symbol]
|
206
210
|
def bitrate=(bitrate)
|
207
|
-
Spotify.session_preferred_bitrate(pointer, bitrate)
|
211
|
+
Spotify.session_preferred_bitrate!(pointer, bitrate)
|
208
212
|
end
|
209
213
|
|
210
214
|
# Loads a Track for playing.
|
data/lib/hallon/playlist.rb
CHANGED
@@ -72,7 +72,6 @@ module Hallon
|
|
72
72
|
# @raise [IndexError] if the underlying track has moved
|
73
73
|
# @raise [Error] if the operation could not be completed
|
74
74
|
#
|
75
|
-
# @param [Integer] index
|
76
75
|
# @param [Boolean] seen true if the track is now seen
|
77
76
|
# @return [Playlist::Track] track at the given index
|
78
77
|
def seen=(seen)
|
@@ -152,6 +151,11 @@ module Hallon
|
|
152
151
|
|
153
152
|
# Waits for the playlist to begin updating and blocks until it is done.
|
154
153
|
#
|
154
|
+
# @note this is done by waiting for the libspotify callback, where libspotify
|
155
|
+
# tells Hallon the playlist update is done.
|
156
|
+
#
|
157
|
+
# @param [Integer] timeout time until the operation times out
|
158
|
+
# @raise [Hallon::TimeoutError] if the upload failed within the load timeout
|
155
159
|
# @return [Playlist]
|
156
160
|
def upload(timeout = Hallon.load_timeout)
|
157
161
|
Timeout.timeout(timeout, Hallon::TimeoutError) do
|
@@ -96,7 +96,7 @@ module Hallon
|
|
96
96
|
container.move(insert_at + 1, @end)
|
97
97
|
end
|
98
98
|
|
99
|
-
# @param [PlaylistContainer]
|
99
|
+
# @param [PlaylistContainer] container_pointer
|
100
100
|
# @param [Range] indices
|
101
101
|
def initialize(container_pointer, indices)
|
102
102
|
@container_ptr = container_pointer
|
@@ -193,19 +193,19 @@ module Hallon
|
|
193
193
|
# @param [String, Playlist, Link] playlist
|
194
194
|
# @param [Boolean] force_create force creation of a new playlist
|
195
195
|
# @return [Playlist, nil] the added playlist, or nil if the operation failed
|
196
|
-
def add(
|
197
|
-
|
198
|
-
unless error = Playlist.invalid_name?(
|
199
|
-
Spotify.playlistcontainer_add_new_playlist!(pointer,
|
196
|
+
def add(playlist, force_create = false)
|
197
|
+
resource = if force_create or not Link.valid?(playlist) and playlist.is_a?(String)
|
198
|
+
unless error = Playlist.invalid_name?(playlist)
|
199
|
+
Spotify.playlistcontainer_add_new_playlist!(pointer, playlist)
|
200
200
|
else
|
201
201
|
raise ArgumentError, error
|
202
202
|
end
|
203
203
|
else
|
204
|
-
link = Link.new(
|
204
|
+
link = Link.new(playlist)
|
205
205
|
Spotify.playlistcontainer_add_playlist!(pointer, link.pointer)
|
206
206
|
end
|
207
207
|
|
208
|
-
Playlist.from(
|
208
|
+
Playlist.from(resource)
|
209
209
|
end
|
210
210
|
|
211
211
|
# Create a new folder with the given name at the end of the container.
|
@@ -331,7 +331,8 @@ module Hallon
|
|
331
331
|
# Wrapper for original API; adjusts indices accordingly.
|
332
332
|
#
|
333
333
|
# @param [Integer] from
|
334
|
-
# @param [Integer]
|
334
|
+
# @param [Integer] infront_of
|
335
|
+
# @param [Boolean] dry_run
|
335
336
|
# @return [Integer] error
|
336
337
|
def move_playlist(from, infront_of, dry_run)
|
337
338
|
infront_of += 1 if from < infront_of
|
@@ -0,0 +1,103 @@
|
|
1
|
+
module Hallon
|
2
|
+
# The Hallon::Scrobbler is responsible for controlling play scrobbling.
|
3
|
+
#
|
4
|
+
# You can construct the scrobbler with different providers to control
|
5
|
+
# scrobbling for each one individually. The scrobbler includes a list
|
6
|
+
# of social providers, methods to adjust the scrobbling of libspotify,
|
7
|
+
# and methods to retrieve the current scrobbling state.
|
8
|
+
class Scrobbler
|
9
|
+
# @return [Array<Symbol>] list of available scrobbling providers
|
10
|
+
def self.providers
|
11
|
+
Spotify.enum_type(:social_provider).symbols
|
12
|
+
end
|
13
|
+
|
14
|
+
# @return [Symbol] social provider
|
15
|
+
attr_reader :provider
|
16
|
+
|
17
|
+
# Initialize the scrobbler with a social provider.
|
18
|
+
#
|
19
|
+
# @note it appears that in libspotify v12.1.56, the only valid provider
|
20
|
+
# is :facebook — all other providers return errors
|
21
|
+
#
|
22
|
+
# @raise [ArgumentError] if the given provider is invalid
|
23
|
+
# @param [Symbol] provider
|
24
|
+
def initialize(provider)
|
25
|
+
provider_to_i = Spotify.enum_value!(provider, "social provider")
|
26
|
+
@provider = Spotify.enum_type(:social_provider)[provider_to_i]
|
27
|
+
end
|
28
|
+
|
29
|
+
# @note if this returns false, it usually means libspotify either has
|
30
|
+
# no scrobbling credentials, or the user has disallowed spotify
|
31
|
+
# from scrobbling to the given provider
|
32
|
+
#
|
33
|
+
# @note this method only works for the :facebook provider; for all other
|
34
|
+
# providers it will always return true
|
35
|
+
#
|
36
|
+
# @return [Boolean] true if scrobbling is possible
|
37
|
+
def possible?
|
38
|
+
case provider
|
39
|
+
when :spotify, :lastfm
|
40
|
+
# libspotify v12.1.56 has a bug with all providers except for :facebook
|
41
|
+
# where the return value is always :invalid_indata; however, the devs
|
42
|
+
# also mentioned the function would always return true for all other
|
43
|
+
# providers anyway
|
44
|
+
true
|
45
|
+
else
|
46
|
+
FFI::Buffer.alloc_out(:bool) do |buffer|
|
47
|
+
Spotify.session_is_scrobbling_possible!(session.pointer, provider, buffer)
|
48
|
+
return ! buffer.read_uchar.zero?
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
# Sets the scrobbling credentials.
|
54
|
+
#
|
55
|
+
# @example setting username and password
|
56
|
+
# scrobbling.credentials = 'kim', 'password'
|
57
|
+
#
|
58
|
+
# @param [Array<Username, Password>] credentials
|
59
|
+
def credentials=(credentials)
|
60
|
+
username, password = Array(credentials)
|
61
|
+
Spotify.session_set_social_credentials!(session.pointer, provider, username, password)
|
62
|
+
end
|
63
|
+
|
64
|
+
# Enables or disables the local scrobbling setting.
|
65
|
+
#
|
66
|
+
# @param [Boolean] scrobble true if you want scrobbling to be enabled
|
67
|
+
def enabled=(scrobble)
|
68
|
+
state = scrobble ? :local_enabled : :local_disabled
|
69
|
+
Spotify.session_set_scrobbling!(session.pointer, provider, state)
|
70
|
+
end
|
71
|
+
|
72
|
+
# @return [Boolean] true if scrobbling (global or local) is enabled.
|
73
|
+
def enabled?
|
74
|
+
FFI::Buffer.alloc_out(:int) do |buffer|
|
75
|
+
Spotify.session_is_scrobbling(session.pointer, provider, buffer)
|
76
|
+
state = read_state(buffer.read_uint)
|
77
|
+
return !! (state =~ /enabled/)
|
78
|
+
end
|
79
|
+
end
|
80
|
+
|
81
|
+
# Sets the local scrobbling state to the global state.
|
82
|
+
#
|
83
|
+
# @return [Scrobbler]
|
84
|
+
def reset
|
85
|
+
tap { Spotify.session_set_scrobbling!(session.pointer, provider, :use_global_setting) }
|
86
|
+
end
|
87
|
+
|
88
|
+
protected
|
89
|
+
|
90
|
+
# Convert an integer state to an actual state symbol.
|
91
|
+
#
|
92
|
+
# @param [Integer] state
|
93
|
+
# @return [Symbol] state as a symbol
|
94
|
+
def read_state(state)
|
95
|
+
Spotify.enum_type(:scrobbling_state)[state]
|
96
|
+
end
|
97
|
+
|
98
|
+
# @return [Hallon::Session]
|
99
|
+
def session
|
100
|
+
Session.instance
|
101
|
+
end
|
102
|
+
end
|
103
|
+
end
|