spotify-ruby-kev 0.2.5
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.github/CONTRIBUTING.md +3 -0
- data/.github/ISSUE_TEMPLATE.md +27 -0
- data/.gitignore +24 -0
- data/.rspec +3 -0
- data/.rubocop.yml +161 -0
- data/.ruby-version +1 -0
- data/.rvm-version +1 -0
- data/.travis.yml +17 -0
- data/CODE_OF_CONDUCT.md +74 -0
- data/COVERAGE.md +148 -0
- data/Gemfile +6 -0
- data/LICENSE +21 -0
- data/README.md +388 -0
- data/Rakefile +23 -0
- data/lib/spotify.rb +17 -0
- data/lib/spotify/accounts.rb +133 -0
- data/lib/spotify/accounts/session.rb +177 -0
- data/lib/spotify/sdk.rb +93 -0
- data/lib/spotify/sdk/.keep +0 -0
- data/lib/spotify/sdk/album.rb +84 -0
- data/lib/spotify/sdk/artist.rb +163 -0
- data/lib/spotify/sdk/base.rb +77 -0
- data/lib/spotify/sdk/connect.rb +75 -0
- data/lib/spotify/sdk/connect/device.rb +362 -0
- data/lib/spotify/sdk/connect/playback_state.rb +143 -0
- data/lib/spotify/sdk/image.rb +44 -0
- data/lib/spotify/sdk/item.rb +157 -0
- data/lib/spotify/sdk/me.rb +155 -0
- data/lib/spotify/sdk/me/info.rb +108 -0
- data/lib/spotify/sdk/model.rb +70 -0
- data/lib/spotify/version.rb +16 -0
- data/spotify-ruby-kev.gemspec +56 -0
- metadata +291 -0
@@ -0,0 +1,163 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Spotify
|
4
|
+
class SDK
|
5
|
+
class Artist < Model
|
6
|
+
##
|
7
|
+
# Do we have the full information for this artist?
|
8
|
+
#
|
9
|
+
# @example
|
10
|
+
# artist = @sdk.connect.playback.artist
|
11
|
+
# artist.full_information? # => false
|
12
|
+
#
|
13
|
+
# @return [FalseClass,TrueClass] is_full_info Does this contain everything?
|
14
|
+
#
|
15
|
+
def full_information?
|
16
|
+
to_h.key?(:images)
|
17
|
+
end
|
18
|
+
|
19
|
+
##
|
20
|
+
# Get full information for this artist by calling /v1/artists/:id
|
21
|
+
#
|
22
|
+
# @example
|
23
|
+
# artist = @sdk.connect.playback.artist
|
24
|
+
# artist.retrieve_full_information! unless artist.full_information?
|
25
|
+
#
|
26
|
+
# @return [TrueClass] success Always returns true.
|
27
|
+
#
|
28
|
+
def retrieve_full_information!
|
29
|
+
unless full_information?
|
30
|
+
parent.send_http_request(:get, "/v1/artists/%s" % id).map do |key, value|
|
31
|
+
send("%s=" % key, value)
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
true
|
36
|
+
end
|
37
|
+
|
38
|
+
##
|
39
|
+
# Helper method for setting the following status.
|
40
|
+
# Requires the `user-follow-modify` scope.
|
41
|
+
# If true, PUT /v1/me/following otherwise DELETE /v1/me/following
|
42
|
+
#
|
43
|
+
# @example
|
44
|
+
# @sdk.playback.item.artist.following = true
|
45
|
+
# @sdk.playback.item.artist.following = false
|
46
|
+
#
|
47
|
+
def following=(should_follow)
|
48
|
+
raise "#following= must be true or false" unless [true, false].include?(should_follow)
|
49
|
+
|
50
|
+
should_follow ? follow! : unfollow!
|
51
|
+
end
|
52
|
+
|
53
|
+
##
|
54
|
+
# Follow the artist.
|
55
|
+
# Requires the `user-follow-modify` scope.
|
56
|
+
# PUT /v1/me/following
|
57
|
+
#
|
58
|
+
# @example
|
59
|
+
# @sdk.playback.item.artist.follow!
|
60
|
+
#
|
61
|
+
# @return [Spotify::SDK::Artist] self Return the artist object, for chaining methods.
|
62
|
+
#
|
63
|
+
def follow!
|
64
|
+
parent.send_http_request(:put, "/v1/me/following?type=artist&ids=%s" % id, http_options: {expect_nil: true})
|
65
|
+
self
|
66
|
+
end
|
67
|
+
|
68
|
+
##
|
69
|
+
# Unfollow the artist.
|
70
|
+
# Requires the `user-follow-modify` scope.
|
71
|
+
# DELETE /v1/me/following
|
72
|
+
#
|
73
|
+
# @example
|
74
|
+
# @sdk.playback.item.artist.unfollow!
|
75
|
+
#
|
76
|
+
# @return [Spotify::SDK::Artist] self Return the artist object, for chaining methods.
|
77
|
+
#
|
78
|
+
def unfollow!
|
79
|
+
parent.send_http_request(:delete, "/v1/me/following?type=artist&ids=%s" % id, http_options: {expect_nil: true})
|
80
|
+
self
|
81
|
+
end
|
82
|
+
|
83
|
+
##
|
84
|
+
# Display the artist's images. If not obtained, request them from the API.
|
85
|
+
#
|
86
|
+
# @example
|
87
|
+
# artist = @sdk.connect.playback.artist
|
88
|
+
# artist.images[0] # => [#<Spotify::SDK::Image>, #<Spotify::SDK::Image>, ...]
|
89
|
+
#
|
90
|
+
# @return [Array] images Contains a list of images, wrapped in Spotify::SDK::Image
|
91
|
+
#
|
92
|
+
def images
|
93
|
+
retrieve_full_information! unless full_information?
|
94
|
+
super.map {|image| Spotify::SDK::Image.new(image, parent) }
|
95
|
+
end
|
96
|
+
|
97
|
+
##
|
98
|
+
# Display the artist's popularity. If not obtained, request them from the API.
|
99
|
+
#
|
100
|
+
# @example
|
101
|
+
# artist = @sdk.connect.playback.artist
|
102
|
+
# artist.popularity # => 90
|
103
|
+
#
|
104
|
+
# @return [Integer] popularity The number of popularity, between 0-100.
|
105
|
+
#
|
106
|
+
def popularity
|
107
|
+
retrieve_full_information! unless full_information?
|
108
|
+
super
|
109
|
+
end
|
110
|
+
|
111
|
+
##
|
112
|
+
# Display the artist's genres. If not obtained, request them from the API.
|
113
|
+
#
|
114
|
+
# @example
|
115
|
+
# artist = @sdk.connect.playback.artist
|
116
|
+
# artist.genres # => ["hip hop", "pop rap", "rap", ...]
|
117
|
+
#
|
118
|
+
# @return [Array] genres An array of genres, denoted in strings.
|
119
|
+
#
|
120
|
+
def genres
|
121
|
+
retrieve_full_information! unless full_information?
|
122
|
+
super
|
123
|
+
end
|
124
|
+
|
125
|
+
##
|
126
|
+
# Return the Spotify URL for this artist.
|
127
|
+
#
|
128
|
+
# @example
|
129
|
+
# artist = @sdk.connect.playback.artist
|
130
|
+
# artist.spotify_url # => "https://open.spotify.com/artist/..."
|
131
|
+
#
|
132
|
+
# @return [String] spotify_url The URL to open this artist on open.spotify.com
|
133
|
+
#
|
134
|
+
def spotify_url
|
135
|
+
external_urls[:spotify]
|
136
|
+
end
|
137
|
+
|
138
|
+
##
|
139
|
+
# Return the Spotify URI for this artist.
|
140
|
+
#
|
141
|
+
# @example
|
142
|
+
# artist = @sdk.connect.playback.artist
|
143
|
+
# artist.spotify_uri # => "spotify:uri:..."
|
144
|
+
#
|
145
|
+
# @return [String] spotify_uri The URI to open this artist in official apps.
|
146
|
+
#
|
147
|
+
alias_attribute :spotify_uri, :uri
|
148
|
+
|
149
|
+
##
|
150
|
+
# Return the followers on Spotify for this artist.
|
151
|
+
#
|
152
|
+
# @example
|
153
|
+
# artist = @sdk.connect.playback.artist
|
154
|
+
# artist.followers # => 13913
|
155
|
+
#
|
156
|
+
# @return [Integer] followers The number of users following this artist.
|
157
|
+
#
|
158
|
+
def followers
|
159
|
+
super[:total]
|
160
|
+
end
|
161
|
+
end
|
162
|
+
end
|
163
|
+
end
|
@@ -0,0 +1,77 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Spotify
|
4
|
+
class SDK
|
5
|
+
##
|
6
|
+
# For each SDK component, we have a Base class. We're using HTTParty.
|
7
|
+
#
|
8
|
+
class Base
|
9
|
+
include HTTParty
|
10
|
+
base_uri "api.spotify.com:443"
|
11
|
+
|
12
|
+
##
|
13
|
+
# Initiate a Spotify SDK Base component.
|
14
|
+
#
|
15
|
+
# @example
|
16
|
+
# @sdk = Spotify::SDK.new(@session)
|
17
|
+
# @auth = Spotify::SDK::Base.new(@sdk)
|
18
|
+
#
|
19
|
+
# @sdk = Spotify::SDK.new(@session)
|
20
|
+
# @sdk.to_hash # => { access_token: ..., expires_at: ... }
|
21
|
+
#
|
22
|
+
# @param [Spotify::SDK] parent An instance of Spotify::SDK as a reference point.
|
23
|
+
#
|
24
|
+
def initialize(parent)
|
25
|
+
@parent = parent
|
26
|
+
@options = {
|
27
|
+
headers: {
|
28
|
+
Authorization: "Bearer %s" % @parent.session.access_token
|
29
|
+
}
|
30
|
+
}
|
31
|
+
end
|
32
|
+
|
33
|
+
##
|
34
|
+
# Handle HTTParty responses.
|
35
|
+
#
|
36
|
+
# @example
|
37
|
+
# # Return the Hash from the JSON response.
|
38
|
+
# send_http_request(:get, "/v1/me/player/devices", @options)
|
39
|
+
#
|
40
|
+
# # Return the raw HTTParty::Response object.
|
41
|
+
# send_http_request(:get, "/v1/me/player/devices", @options.merge({http_options: { raw: true }}))
|
42
|
+
#
|
43
|
+
# # Return true for HTTP requests that return a 200 OK with an empty response.
|
44
|
+
# send_http_request(:put, "/v1/me/player/pause", @options.merge({http_options: { expect_nil: true }}))
|
45
|
+
#
|
46
|
+
# @param [Symbol] method The HTTP method you want to perform. Examples are :get, :post, :put, :delete
|
47
|
+
# @param [String] endpoint The HTTP endpoint you'd like to call. Example: /v1/me
|
48
|
+
# @param [Hash] override_opts Any headers, HTTParty config or application-specific config (see `http_options`)
|
49
|
+
# @return [Hash,HTTParty::Response,TrueClass] response The response from the HTTP request.
|
50
|
+
#
|
51
|
+
# TODO: Address and fix cyclomatic & code complexity issues by Rubocop.
|
52
|
+
# rubocop:disable CyclomaticComplexity, PerceivedComplexity, AbcSize
|
53
|
+
def send_http_request(method, endpoint, override_opts={})
|
54
|
+
opts = {
|
55
|
+
raw: false,
|
56
|
+
expect_nil: false
|
57
|
+
}.merge(override_opts[:http_options].presence || {})
|
58
|
+
|
59
|
+
httparty = self.class.send(method, endpoint, @options.merge(override_opts))
|
60
|
+
response = httparty.parsed_response
|
61
|
+
response = response.try(:deep_symbolize_keys) || response
|
62
|
+
raise response[:error][:message] if response.is_a?(Hash) && response[:error].present?
|
63
|
+
return httparty if opts[:raw] == true
|
64
|
+
|
65
|
+
response = opts[:expect_nil] ? true : raise("No response returned") if response.nil?
|
66
|
+
response
|
67
|
+
end
|
68
|
+
# rubocop:enable CyclomaticComplexity, PerceivedComplexity, AbcSize
|
69
|
+
|
70
|
+
def inspect # :nodoc:
|
71
|
+
"#<%s:0x00%x>" % [self.class.name, (object_id << 1)]
|
72
|
+
end
|
73
|
+
|
74
|
+
attr_reader :parent
|
75
|
+
end
|
76
|
+
end
|
77
|
+
end
|
@@ -0,0 +1,75 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Spotify
|
4
|
+
class SDK
|
5
|
+
class Connect < Base
|
6
|
+
##
|
7
|
+
# Get the current playback.
|
8
|
+
# GET /v1/me/player
|
9
|
+
#
|
10
|
+
# @example
|
11
|
+
# playback = @sdk.connect.playback
|
12
|
+
#
|
13
|
+
# @see https://developer.spotify.com/console/get-user-player/
|
14
|
+
# @see https://developer.spotify.com/documentation/web-api/reference/player/get-information-about-the-users-current-playback/
|
15
|
+
#
|
16
|
+
# @param [String] market The market you'd like to request.
|
17
|
+
# @param [Hash] override_opts Custom options for HTTParty.
|
18
|
+
# @return [Spotify::SDK::Connect::PlaybackState] playback_state Return the playback state object.
|
19
|
+
#
|
20
|
+
def playback(market="from_token", override_opts={})
|
21
|
+
playback_state = send_http_request(:get, "/v1/me/player?market=%s" % market, override_opts)
|
22
|
+
Spotify::SDK::Connect::PlaybackState.new(playback_state, self)
|
23
|
+
end
|
24
|
+
|
25
|
+
##
|
26
|
+
# Collect all the user's available devices.
|
27
|
+
# GET /v1/me/player/devices
|
28
|
+
#
|
29
|
+
# @example
|
30
|
+
# @sdk.connect.devices # => [#<Spotify::SDK::Connect::Device:...>, ...]
|
31
|
+
#
|
32
|
+
# @see https://developer.spotify.com/console/get-users-available-devices/
|
33
|
+
#
|
34
|
+
# @param [Hash] override_opts Custom options for HTTParty.
|
35
|
+
# @return [Array] devices A list of all devices.
|
36
|
+
#
|
37
|
+
def devices(override_opts={})
|
38
|
+
response = send_http_request(:get, "/v1/me/player/devices", override_opts)
|
39
|
+
response[:devices].map do |device|
|
40
|
+
Spotify::SDK::Connect::Device.new(device, self)
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
##
|
45
|
+
# Collect all the active devices.
|
46
|
+
#
|
47
|
+
# @example
|
48
|
+
# @sdk.connect.active_devices # => [#<Spotify::SDK::Connect::Device:...>, ...]
|
49
|
+
#
|
50
|
+
# @see https://developer.spotify.com/console/get-users-available-devices/
|
51
|
+
#
|
52
|
+
# @param [Hash] override_opts Custom options for HTTParty.
|
53
|
+
# @return [Array] devices A list of all devices that are marked as `is_active`.
|
54
|
+
#
|
55
|
+
def active_devices(override_opts={})
|
56
|
+
devices(override_opts).select(&:active?)
|
57
|
+
end
|
58
|
+
|
59
|
+
##
|
60
|
+
# Collect the first active device.
|
61
|
+
#
|
62
|
+
# @example
|
63
|
+
# @sdk.connect.active_device # => #<Spotify::SDK::Connect::Device:...>
|
64
|
+
#
|
65
|
+
# @see https://developer.spotify.com/console/get-users-available-devices/
|
66
|
+
#
|
67
|
+
# @param [Hash] override_opts Custom options for HTTParty.
|
68
|
+
# @return [Array,NilClass] device The first device with `is_active`. If no device found, returns `nil`.
|
69
|
+
#
|
70
|
+
def active_device(override_opts={})
|
71
|
+
devices(override_opts).find(&:active?)
|
72
|
+
end
|
73
|
+
end
|
74
|
+
end
|
75
|
+
end
|
@@ -0,0 +1,362 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Spotify
|
4
|
+
class SDK
|
5
|
+
class Connect
|
6
|
+
class Device < Model
|
7
|
+
##
|
8
|
+
# Get the device's volume.
|
9
|
+
#
|
10
|
+
# @example
|
11
|
+
# device = @sdk.connect.devices[0]
|
12
|
+
# device.volume
|
13
|
+
#
|
14
|
+
# @return [Integer] volume Get the volume. Between 0 and 100.
|
15
|
+
#
|
16
|
+
alias_attribute :volume, :volume_percent
|
17
|
+
|
18
|
+
##
|
19
|
+
# Is the device active?
|
20
|
+
#
|
21
|
+
# @example
|
22
|
+
# device = @sdk.connect.devices[0]
|
23
|
+
# device.active?
|
24
|
+
#
|
25
|
+
# @return [Boolean] is_active Bool of whether device is active.
|
26
|
+
#
|
27
|
+
alias_attribute :active?, :is_active
|
28
|
+
|
29
|
+
##
|
30
|
+
# Is the device's session private?
|
31
|
+
#
|
32
|
+
# @example
|
33
|
+
# device = @sdk.connect.devices[0]
|
34
|
+
# device.private_session?
|
35
|
+
#
|
36
|
+
# @return [Boolean] is_private_session Bool of whether device has a private session.
|
37
|
+
#
|
38
|
+
alias_attribute :private_session?, :is_private_session
|
39
|
+
|
40
|
+
##
|
41
|
+
# Is the device restricted?
|
42
|
+
#
|
43
|
+
# @example
|
44
|
+
# device = @sdk.connect.devices[0]
|
45
|
+
# device.restricted?
|
46
|
+
#
|
47
|
+
# @return [Boolean] is_restricted Bool of whether device is restricted.
|
48
|
+
#
|
49
|
+
alias_attribute :restricted?, :is_restricted
|
50
|
+
|
51
|
+
##
|
52
|
+
# Get the currently playing track.
|
53
|
+
# Alias to Spotify::SDK::Connect#playback
|
54
|
+
#
|
55
|
+
# @example
|
56
|
+
# device = @sdk.connect.devices[0]
|
57
|
+
# device.playback
|
58
|
+
#
|
59
|
+
# # Same as calling the following:
|
60
|
+
# @sdk.connect.playback
|
61
|
+
#
|
62
|
+
# @see lib/spotify/sdk/connect.rb
|
63
|
+
#
|
64
|
+
# @return [Spotify::SDK::Connect::PlaybackState] self Return the playback state object.
|
65
|
+
#
|
66
|
+
def playback
|
67
|
+
parent.playback
|
68
|
+
end
|
69
|
+
|
70
|
+
##
|
71
|
+
# Play the currently playing track on device.
|
72
|
+
# PUT /v1/me/player/play
|
73
|
+
#
|
74
|
+
# @example
|
75
|
+
# device = @sdk.connect.devices[0]
|
76
|
+
#
|
77
|
+
# # Play from a playlist, album from a specific index in that list.
|
78
|
+
# # For example, play the 9th item on X playlist.
|
79
|
+
# device.play!(
|
80
|
+
# index: 5,
|
81
|
+
# context: "spotify:album:5ht7ItJgpBH7W6vJ5BqpPr",
|
82
|
+
# position_ms: 0
|
83
|
+
# )
|
84
|
+
#
|
85
|
+
# # Play any Spotify URI. Albums, artists, tracks, playlists, and more.
|
86
|
+
# device.play!(
|
87
|
+
# uri: "spotify:track:5MqkZd7a7u7N7hKMqquL2U",
|
88
|
+
# position_ms: 0
|
89
|
+
# )
|
90
|
+
#
|
91
|
+
# # Similar to just uri, but you can define the context.
|
92
|
+
# # Useful for playing a track that is part of a playlist, and you want the next
|
93
|
+
# # songs to play from that particular context.
|
94
|
+
# device.play!(
|
95
|
+
# uri: "spotify:track:5MqkZd7a7u7N7hKMqquL2U",
|
96
|
+
# context: "spotify:album:5ht7ItJgpBH7W6vJ5BqpPr",
|
97
|
+
# position_ms: 0
|
98
|
+
# )
|
99
|
+
#
|
100
|
+
# # Play a track, and immediately seek to 60 seconds.
|
101
|
+
# device.play!(
|
102
|
+
# index: 5,
|
103
|
+
# context: "spotify:album:5ht7ItJgpBH7W6vJ5BqpPr",
|
104
|
+
# position_ms: 60 * 1000
|
105
|
+
# )
|
106
|
+
#
|
107
|
+
# @see https://developer.spotify.com/console/put-play/
|
108
|
+
#
|
109
|
+
# @param [Hash] config The play config you'd like to set. See code examples.
|
110
|
+
# @return [Spotify::SDK::Connect::Device] self Return itself, so chained methods can be supported.
|
111
|
+
#
|
112
|
+
# rubocop:disable AbcSize
|
113
|
+
def play!(config)
|
114
|
+
payload = case config.keys
|
115
|
+
when %i[index context position_ms]
|
116
|
+
{context_uri: config[:context],
|
117
|
+
offset: {position: config[:index]},
|
118
|
+
position_ms: config[:position_ms]}
|
119
|
+
when %i[uri position_ms]
|
120
|
+
{uris: [config[:uri]],
|
121
|
+
position_ms: config[:position_ms]}
|
122
|
+
when %i[uri context position_ms]
|
123
|
+
{context_uri: config[:context],
|
124
|
+
offset: {uri: config[:uri]},
|
125
|
+
position_ms: config[:position_ms]}
|
126
|
+
else
|
127
|
+
raise <<-ERROR.strip_heredoc.strip
|
128
|
+
Unrecognized play instructions.
|
129
|
+
See https://www.rubydoc.info/github/bih/spotify-ruby/Spotify/SDK/Connect/Device#play!-instance_method for details.
|
130
|
+
ERROR
|
131
|
+
end
|
132
|
+
|
133
|
+
parent.send_http_request(:put, "/v1/me/player/play?device_id=%s" % id, http_options: {expect_nil: true},
|
134
|
+
body: payload.to_json)
|
135
|
+
self
|
136
|
+
end
|
137
|
+
# rubocop:enable AbcSize
|
138
|
+
|
139
|
+
##
|
140
|
+
# Resume the currently playing track on device.
|
141
|
+
# PUT /v1/me/player/play
|
142
|
+
#
|
143
|
+
# @example
|
144
|
+
# device = @sdk.connect.devices[0]
|
145
|
+
# device.resume!
|
146
|
+
#
|
147
|
+
# @see https://developer.spotify.com/console/put-play/
|
148
|
+
#
|
149
|
+
# @return [Spotify::SDK::Connect::Device] self Return itself, so chained methods can be supported.
|
150
|
+
#
|
151
|
+
def resume!
|
152
|
+
parent.send_http_request(:put, "/v1/me/player/play?device_id=%s" % id, http_options: {expect_nil: true})
|
153
|
+
self
|
154
|
+
end
|
155
|
+
|
156
|
+
##
|
157
|
+
# Pause the currently playing track on device.
|
158
|
+
# PUT /v1/me/player/pause
|
159
|
+
#
|
160
|
+
# @example
|
161
|
+
# device = @sdk.connect.devices[0]
|
162
|
+
# device.pause!
|
163
|
+
#
|
164
|
+
# @see https://developer.spotify.com/console/put-pause/
|
165
|
+
#
|
166
|
+
# @return [Spotify::SDK::Connect::Device] self Return itself, so chained methods can be supported.
|
167
|
+
#
|
168
|
+
def pause!
|
169
|
+
parent.send_http_request(:put, "/v1/me/player/pause?device_id=%s" % id, http_options: {expect_nil: true})
|
170
|
+
self
|
171
|
+
end
|
172
|
+
|
173
|
+
##
|
174
|
+
# Skip to previous track on device.
|
175
|
+
# POST /v1/me/player/previous
|
176
|
+
#
|
177
|
+
# @example
|
178
|
+
# device = @sdk.connect.devices[0]
|
179
|
+
# device.previous!
|
180
|
+
#
|
181
|
+
# @see https://developer.spotify.com/console/put-previous/
|
182
|
+
#
|
183
|
+
# @return [Spotify::SDK::Connect::Device] self Return itself, so chained methods can be supported.
|
184
|
+
#
|
185
|
+
def previous!
|
186
|
+
parent.send_http_request(:post, "/v1/me/player/previous?device_id=%s" % id, http_options: {expect_nil: true})
|
187
|
+
self
|
188
|
+
end
|
189
|
+
|
190
|
+
##
|
191
|
+
# Skip to next track on device.
|
192
|
+
# POST /v1/me/player/next
|
193
|
+
#
|
194
|
+
# @example
|
195
|
+
# device = @sdk.connect.devices[0]
|
196
|
+
# device.next!
|
197
|
+
#
|
198
|
+
# @see https://developer.spotify.com/console/put-next/
|
199
|
+
#
|
200
|
+
# @return [Spotify::SDK::Connect::Device] self Return itself, so chained methods can be supported.
|
201
|
+
#
|
202
|
+
def next!
|
203
|
+
parent.send_http_request(:post, "/v1/me/player/next?device_id=%s" % id, http_options: {expect_nil: true})
|
204
|
+
self
|
205
|
+
end
|
206
|
+
|
207
|
+
##
|
208
|
+
# Set volume for current device.
|
209
|
+
# PUT /v1/me/player/volume
|
210
|
+
#
|
211
|
+
# @example
|
212
|
+
# device = @sdk.connect.devices[0]
|
213
|
+
# device.change_volume!(30)
|
214
|
+
#
|
215
|
+
# # or
|
216
|
+
#
|
217
|
+
# device = @sdk.connect.devices[0]
|
218
|
+
# device.volume = 30
|
219
|
+
#
|
220
|
+
# @see https://developer.spotify.com/console/put-volume/
|
221
|
+
#
|
222
|
+
# @param [Integer] volume_percent The 0-100 value to change the volume to. 100 is maximum.
|
223
|
+
# @return [Spotify::SDK::Connect::Device] self Return itself, so chained methods can be supported.
|
224
|
+
#
|
225
|
+
def change_volume!(volume_percent)
|
226
|
+
raise "Must be an integer" unless volume_percent.is_a?(Integer)
|
227
|
+
|
228
|
+
endpoint = "/v1/me/player/volume?volume_percent=%i&device_id=%s" % [volume_percent, id]
|
229
|
+
opts = {http_options: {expect_nil: true}}
|
230
|
+
parent.send_http_request(:put, endpoint, opts)
|
231
|
+
self
|
232
|
+
end
|
233
|
+
|
234
|
+
alias_method :volume=, :change_volume!
|
235
|
+
|
236
|
+
##
|
237
|
+
# Seek position (in milliseconds) for the currently playing track on the device.
|
238
|
+
# PUT /v1/me/player/seek
|
239
|
+
#
|
240
|
+
# @example
|
241
|
+
# device = @sdk.connect.devices[0]
|
242
|
+
# device.seek_ms!(4000)
|
243
|
+
#
|
244
|
+
# @see https://developer.spotify.com/console/put-seek/
|
245
|
+
#
|
246
|
+
# @param [Integer] position_ms In milliseconds, where to seek in the current track on device.
|
247
|
+
# @return [Spotify::SDK::Connect::Device] self Return itself, so chained methods can be supported.
|
248
|
+
#
|
249
|
+
def seek_ms!(position_ms)
|
250
|
+
raise "Must be an integer" unless position_ms.is_a?(Integer)
|
251
|
+
|
252
|
+
endpoint = "/v1/me/player/seek?position_ms=%i&device_id=%s" % [position_ms, id]
|
253
|
+
opts = {http_options: {expect_nil: true}}
|
254
|
+
parent.send_http_request(:put, endpoint, opts)
|
255
|
+
self
|
256
|
+
end
|
257
|
+
|
258
|
+
alias_method :position_ms=, :seek_ms!
|
259
|
+
|
260
|
+
##
|
261
|
+
# Set repeat mode for current device.
|
262
|
+
# PUT /v1/me/player/repeat
|
263
|
+
#
|
264
|
+
# @example
|
265
|
+
# device = @sdk.connect.devices[0]
|
266
|
+
# device.repeat!(:track)
|
267
|
+
# device.repeat!(:context)
|
268
|
+
# device.repeat!(:off)
|
269
|
+
#
|
270
|
+
# @see https://developer.spotify.com/console/put-repeat/
|
271
|
+
#
|
272
|
+
# @param [Boolean] state What to set the repeat state to - :track, :context, or :off
|
273
|
+
# @return [Spotify::SDK::Connect::Device] self Return itself, so chained methods can be supported.
|
274
|
+
#
|
275
|
+
def repeat!(state)
|
276
|
+
raise "Must be :track, :context, or :off" unless %i[track context off].include?(state)
|
277
|
+
|
278
|
+
endpoint = "/v1/me/player/repeat?state=%s&device_id=%s" % [state, id]
|
279
|
+
opts = {http_options: {expect_nil: true}}
|
280
|
+
parent.send_http_request(:put, endpoint, opts)
|
281
|
+
self
|
282
|
+
end
|
283
|
+
|
284
|
+
alias_method :repeat=, :repeat!
|
285
|
+
|
286
|
+
##
|
287
|
+
# Set shuffle for current device.
|
288
|
+
# PUT /v1/me/player/shuffle
|
289
|
+
#
|
290
|
+
# @example
|
291
|
+
# device = @sdk.connect.devices[0]
|
292
|
+
# device.shuffle!(true)
|
293
|
+
#
|
294
|
+
# @see https://developer.spotify.com/console/put-shuffle/
|
295
|
+
#
|
296
|
+
# @param [Boolean] state The true/false of if you'd like to set shuffle on.
|
297
|
+
# @return [Spotify::SDK::Connect::Device] self Return itself, so chained methods can be supported.
|
298
|
+
#
|
299
|
+
def shuffle!(state)
|
300
|
+
raise "Must be true or false" unless [true, false].include?(state)
|
301
|
+
|
302
|
+
endpoint = "/v1/me/player/shuffle?state=%s&device_id=%s" % [state, id]
|
303
|
+
opts = {http_options: {expect_nil: true}}
|
304
|
+
parent.send_http_request(:put, endpoint, opts)
|
305
|
+
self
|
306
|
+
end
|
307
|
+
|
308
|
+
alias_method :shuffle=, :shuffle!
|
309
|
+
|
310
|
+
##
|
311
|
+
# Transfer a user's playback to another device, and continue playing.
|
312
|
+
# PUT /v1/me/player
|
313
|
+
#
|
314
|
+
# @example
|
315
|
+
# device = @sdk.connect.devices[0]
|
316
|
+
# device.transfer_playback!
|
317
|
+
#
|
318
|
+
# @see https://developer.spotify.com/console/transfer-a-users-playback/
|
319
|
+
#
|
320
|
+
# @return [Spotify::SDK::Connect::Device] self Return itself, so chained methods can be supported.
|
321
|
+
#
|
322
|
+
def transfer_playback!
|
323
|
+
transfer_playback_method(playing: true)
|
324
|
+
self
|
325
|
+
end
|
326
|
+
|
327
|
+
##
|
328
|
+
# Transfer a user's playback to another device, and pause.
|
329
|
+
# PUT /v1/me/player
|
330
|
+
#
|
331
|
+
# @example
|
332
|
+
# device = @sdk.connect.devices[0]
|
333
|
+
# device.transfer_state!
|
334
|
+
#
|
335
|
+
# @see https://developer.spotify.com/console/transfer-a-users-playback/
|
336
|
+
#
|
337
|
+
# @return [Spotify::SDK::Connect::Device] self Return itself, so chained methods can be supported.
|
338
|
+
#
|
339
|
+
def transfer_state!
|
340
|
+
transfer_playback_method(playing: false)
|
341
|
+
self
|
342
|
+
end
|
343
|
+
|
344
|
+
private
|
345
|
+
|
346
|
+
def transfer_playback_method(playing:) # :nodoc:
|
347
|
+
override_opts = {
|
348
|
+
http_options: {
|
349
|
+
expect_nil: true
|
350
|
+
},
|
351
|
+
body: {
|
352
|
+
device_ids: [id],
|
353
|
+
play: playing
|
354
|
+
}.to_json
|
355
|
+
}
|
356
|
+
|
357
|
+
parent.send_http_request(:put, "/v1/me/player", override_opts)
|
358
|
+
end
|
359
|
+
end
|
360
|
+
end
|
361
|
+
end
|
362
|
+
end
|