spotify-ruby-kev 0.2.5
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.
- 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
|