spotify-ruby-kev 0.2.5

Sign up to get free protection for your applications and to get access to all the features.
data/Gemfile ADDED
@@ -0,0 +1,6 @@
1
+ # frozen_string_literal: true
2
+
3
+ source "https://rubygems.org"
4
+
5
+ # Specify your gem's dependencies in spotify.gemspec
6
+ gemspec
data/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ The MIT License (MIT)
2
+
3
+ Copyright (c) 2018 Bilawal Hameed
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in
13
+ all copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21
+ THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,388 @@
1
+ <!-- prettier-ignore-start -->
2
+ <img src="docs/theme/assets/images/logo.png" width="400" />
3
+
4
+ [![Build Status](https://travis-ci.org/bih/spotify-ruby.svg?branch=master)][Build Status]
5
+ [![Maintainability](https://api.codeclimate.com/v1/badges/89410e6302b5562c658a/maintainability)][Maintainability]
6
+ [![Test Coverage](https://api.codeclimate.com/v1/badges/89410e6302b5562c658a/test_coverage)][Test Coverage]
7
+ [![Gem Version](https://badge.fury.io/rb/spotify-ruby.svg)][Gem Version]
8
+ [![Code Triagers Badge](https://www.codetriage.com/bih/spotify-ruby/badges/users.svg)][Code Triagers Badge]
9
+
10
+ The developer-friendly, opinionated Ruby SDK for [Spotify]. Works on Ruby 2.4+
11
+
12
+ 🎨 [Website] | 💖 [Contributing] | 📖 [SDK Reference] | 🔒 [Code of Conduct](#code-of-conduct)
13
+
14
+ ## Contents
15
+
16
+ - [Introduction](#introduction)
17
+ - [Install](#install)
18
+ - [With Bundler](#with-bundler)
19
+ - [Manual Install](#manual-install)
20
+ - [Configuration](#configuration)
21
+ - [Your App Credentials](#your-app-credentials)
22
+ - [Authorization](#authorization)
23
+ - [Creating a Session](#creating-a-session)
24
+ - [Recreating a Session](#recreating-a-session)
25
+ - [Using the SDK](#using-the-sdk)
26
+ - [Spotify Connect API](#spotify-connect-api)
27
+ - [Me API](#me-api)
28
+ - [Listening History API](#listening-history-api)
29
+ - [Following API](#following-api)
30
+ - [Contributing](#contributing)
31
+ - [Community Guidelines](#community-guidelines)
32
+ - [Code of Conduct](#code-of-conduct)
33
+ - [Getting Started](#getting-started)
34
+ - [Releasing a Change](#releasing-a-change)
35
+ - [License](#license)
36
+
37
+ ## Introduction
38
+
39
+ Hey! I'm a Developer Advocate at [Spotify], and I wrote this Ruby SDK to explore how to build a SDK that is TADA:
40
+
41
+ 1. **🧒 Thoughtfully inclusive for beginners.** Everything we do should think about beginners from the start. From having an enforced [Code of Conduct] policy to building great documentation, tooling, and an empathetic feedback process. Designing for beginners is designing for longevity.
42
+
43
+ 1. **☁️ Agnostic to minor changes.** APIs change all the time. We should be opinionated enough that our software should break with major changes, but flexible enough to work perfectly fine with minor changes. Our code should only depend on critical data, such as IDs.
44
+
45
+ 1. **🌈 Delightful for developers.** Writing the SDK and using the SDK should be equally delightful. Granted, this is a challenging goal; but with solid information architecture, well-crafted opinions, clear and helpful error messages, and software that doesn't get in your way - we will create quite lovely software.
46
+
47
+ 1. **✨ A maintained production-level.** It doesn't take experts to write production-level code; all it takes is considerate guidance from the community. We should write software that we and others [trust to do what it is intended to do](https://hackernoon.com/im-harvesting-credit-card-numbers-and-passwords-from-your-site-here-s-how-9a8cb347c5b5). We care about [Semantic Versioning] for clear version changes.
48
+
49
+ _Disclaimer: This SDK is NOT owned or supported by Spotify. It remains a personal project of mine. If you are a commercial partner of Spotify and wish to use this SDK, be aware you are using it at your own risk._
50
+
51
+ ## Install
52
+
53
+ ### With Bundler
54
+
55
+ Add this line to your application's `Gemfile`:
56
+
57
+ ```ruby
58
+ gem "spotify-ruby"
59
+ ```
60
+
61
+ And then execute in your Terminal:
62
+
63
+ ```bash
64
+ $ bundle install
65
+ ```
66
+
67
+ Finally you can include the SDK via `Bundler.require`:
68
+
69
+ ```ruby
70
+ require "bundler"
71
+ Bundler.require
72
+ ```
73
+
74
+ ### Manual Install
75
+
76
+ Or, you can install manually by executing this in your Terminal:
77
+
78
+ ```bash
79
+ $ gem install spotify-ruby
80
+ ```
81
+
82
+ Then you can include the SDK in your Ruby project:
83
+
84
+ ```ruby
85
+ require "spotify-ruby"
86
+ ```
87
+
88
+ ## Configuration
89
+
90
+ You'll firstly need to register your client ID on [developer.spotify.com]. You should receive a Client ID and Client Secret which we'll need to continue.
91
+
92
+ ### Your App Credentials
93
+
94
+ As mentioned above, you'll need to register your client ID. We recommend you that you use a different set of client IDs for development and production. We'll need to use those credentials in order to use any of Spotify's APIs.
95
+
96
+ To define your app credentials, you'll need to create an instance of `Spotify::Accounts`:
97
+
98
+ ```ruby
99
+ @accounts = Spotify::Accounts.new
100
+ @accounts.client_id = "spotify client ID"
101
+ @accounts.client_secret = "spotify client secret"
102
+ @accounts.redirect_uri = "redirect URI"
103
+ ```
104
+
105
+ Alternatively, these credentials can be supplied as environment variables when running your application:
106
+
107
+ ```ruby
108
+ @accounts = Spotify::Accounts.new # fetches configuration from ENV
109
+ ```
110
+
111
+ The respective environment variables you'll need to set are:
112
+
113
+ | Environment Variable | Description | Required? |
114
+ | ------------------------ | ----------------------------------------- | ------------- |
115
+ | `SPOTIFY_CLIENT_ID` | Your Spotify Client ID | **Yes** |
116
+ | `SPOTIFY_CLIENT_SECRET` | Your Spotify Client Secret | **Yes** |
117
+ | `SPOTIFY_REDIRECT_URI` | Your Spotify Redirect URI (must be exact) | **Yes** |
118
+
119
+ ### Authorization
120
+
121
+ In order to use Spotify's APIs on a user's behalf, you'll need to use the Spotify [Accounts API] to redirect them to `https://accounts.spotify.com`. They will then need to explicitly approve your application and what data you're asking for (technically referred to as authorization scopes).
122
+
123
+ **Recommended for production:** To request specific data, read our [Authorization Scopes] reference, and then execute:
124
+
125
+ ```ruby
126
+ @accounts.authorize_url({
127
+ scope: "user-read-private user-read-email user-top-read"
128
+ }) # => "https://accounts.spotify.com/authorize?..."
129
+ ```
130
+
131
+ **Recommended for exploration / local development:** Or, to request all data, you can execute:
132
+
133
+ ```ruby
134
+ @accounts.authorize_url # => "https://accounts.spotify.com/authorize?..."
135
+ ```
136
+
137
+ ### Creating a Session
138
+
139
+ Each session lasts 60 minutes. New sessions can be generated when you have a valid `refresh_token` (they become invalid [if a user revokes your application](https://support.spotify.com/uk/account_payment_help/privacy/revoke-access-from-3rd-party-app/)).
140
+
141
+ After a user has authorized your application, they'll be sent to your `redirect_uri` defined in [Your App Credentials](#your-app-credentials) with a `code` parameter. We can use this to create a `Spotify::Session`:
142
+
143
+ ```ruby
144
+ @session = @accounts.exchange_for_session(params[:code])
145
+ ```
146
+
147
+ We can check when the session expires, and when we should refresh:
148
+
149
+ ```ruby
150
+ @session.expires_at # => 2018-07-08 22:40:15 +0200
151
+
152
+ if @session.expired?
153
+ @session.refresh!
154
+ end
155
+ ```
156
+
157
+ You'll then be able to use `@session` in the `Spotify::SDK` object. See the [Using the SDK](#using-the-sdk) section below.
158
+
159
+ ### Recreating a Session
160
+
161
+ We don't want to send the user to `https://accounts.spotify.com/...` every time they want to use your application. For this case, we'll need to export the `refresh_token` and persist it somewhere:
162
+
163
+ ```ruby
164
+ @session.refresh_token # => "BQASNDMelPsTdJMNMZfWdbxsuuM1FiBxvVzasqWkwYtgpjXJO60Gm51R0LO_-3Q5MfzCU0xIrbIFs7ZlMQrVJeRwN1_Ffa3sIJn_KW6LO8vA44fYc85oz48TuBuZsT2gzr4L"
165
+ ```
166
+
167
+ Then you can repeatedly create a session with just a refresh token and running `refresh!`:
168
+
169
+ ```ruby
170
+ @session = Spotify::Session.from_refresh_token(@accounts, "refresh_token here")
171
+ @session.expired? # => true
172
+ @session.refresh!
173
+ @session.expired? # => false
174
+ ```
175
+
176
+ ## Using the SDK
177
+
178
+ To create an instance of the Spotify SDK, you'll need the `@session` from above and pass it to `Spotify::SDK` as follows:
179
+
180
+ ```ruby
181
+ @session = Spotify::Session.from_refresh_token(@accounts, "refresh_token here")
182
+ @session.refresh!
183
+
184
+ @sdk = Spotify::SDK.new(@session)
185
+ ```
186
+
187
+ ### Spotify Connect API
188
+
189
+ With [Spotify Connect], you can take your music experience anywhere on over 300 devices. And you can read and control most devices programmatically through the SDK:
190
+
191
+ #### Read your devices\*
192
+
193
+ ```ruby
194
+ @sdk.connect.devices # => [#<Spotify::SDK::Connect::Device:...>, ...]
195
+
196
+ @sdk.connect.devices[0].active?
197
+ @sdk.connect.devices[0].private_session?
198
+ @sdk.connect.devices[0].volume
199
+ @sdk.connect.devices[0].restricted?
200
+ ```
201
+
202
+ #### Read current playback\*
203
+
204
+ ```ruby
205
+ @sdk.connect.playback
206
+ @sdk.connect.playback.playing? # => true
207
+ @sdk.connect.playback.device.private_session? # => false
208
+ @sdk.connect.playback.shuffling? # => false
209
+ @sdk.connect.playback.repeat_mode # => :context
210
+ @sdk.connect.playback.position_percentage # => 4.53
211
+ @sdk.connect.playback.artist.name # => "Ed Sheeran"
212
+ @sdk.connect.playback.item.album.name # => "÷"
213
+ ```
214
+
215
+ #### Control playback\*
216
+
217
+ ```ruby
218
+ @sdk.connect.devices[0].play!({
219
+ uri: "spotify:track:0tgVpDi06FyKpA1z0VMD4v",
220
+ position_ms: 0
221
+ })
222
+
223
+ @sdk.connect.devices[0].pause!
224
+ @sdk.connect.devices[0].resume!
225
+ @sdk.connect.devices[0].volume = 80
226
+ @sdk.connect.devices[0].previous!
227
+ @sdk.connect.devices[0].next!
228
+ @sdk.connect.devices[0].position_ms = 3_000
229
+ @sdk.connect.devices[0].shuffle = false
230
+ @sdk.connect.devices[0].repeat_mode = :context
231
+ ```
232
+
233
+ #### Transfer playback\*
234
+
235
+ This will transfer state, and start playback.
236
+
237
+ ```ruby
238
+ @sdk.connect.devices[0].transfer_playback!
239
+ ```
240
+
241
+ #### Transfer state\*
242
+
243
+ This will transfer state, and pause playback.
244
+
245
+ ```ruby
246
+ @sdk.connect.devices[0].transfer_state!
247
+ ```
248
+
249
+ ### Me API
250
+
251
+ This allows you to perform specific actions on behalf of a user.
252
+
253
+ #### My information\*
254
+
255
+ ```ruby
256
+ @sdk.me.info
257
+ @sdk.me.info.free? # => false
258
+ @sdk.me.info.premium? # => true
259
+ @sdk.me.info.birthdate # => 1980-01-01
260
+ @sdk.me.info.display_name? # => true
261
+ @sdk.me.info.display_name # => "ABC Smith"
262
+ @sdk.me.info.images[0].url # => "https://profile-images.scdn.co/userprofile/default/..."
263
+ @sdk.me.info.followers # => 4913313
264
+ @sdk.me.info.spotify_uri # => "spotify:user:abcsmith"
265
+ @sdk.me.info.spotify_url # => "https://open.spotify.com/user/abcsmith"
266
+ ```
267
+
268
+ ### Listening History API
269
+
270
+ #### My recently played tracks (up to last 50)\*
271
+
272
+ ```ruby
273
+ @sdk.me.history(10) # => [#<Spotify::SDK::Item...>, ...]
274
+ @sdk.me.history(10).size # => 10
275
+ @sdk.me.history(50) # => [#<Spotify::SDK::Item...>, ...]
276
+ @sdk.me.history(50).size # => 50
277
+ ```
278
+
279
+ ### Following API
280
+
281
+ #### Follow an artist\*
282
+
283
+ ```ruby
284
+ @sdk.playback.item.artist.follow!
285
+ ```
286
+
287
+ #### Unfollow an artist\*
288
+
289
+ ```ruby
290
+ @sdk.playback.item.artist.unfollow!
291
+ ```
292
+
293
+ #### Check if following Spotify artists?\*
294
+
295
+ ```ruby
296
+ @sdk.me.following_artists?(%w(3TVXtAsR1Inumwj472S9r4 6LuN9FCkKOj5PcnpouEgny 69GGBxA162lTqCwzJG5jLp))
297
+ # => {
298
+ # "3TVXtAsR1Inumwj472S9r4" => false,
299
+ # "6LuN9FCkKOj5PcnpouEgny" => true,
300
+ # "69GGBxA162lTqCwzJG5jLp" => false
301
+ # }
302
+ ```
303
+
304
+ #### Check if following Spotify users?\*
305
+
306
+ ```ruby
307
+ @sdk.me.following_users?(%w(3TVXtAsR1Inumwj472S9r4 6LuN9FCkKOj5PcnpouEgny 69GGBxA162lTqCwzJG5jLp))
308
+ # => {
309
+ # "3TVXtAsR1Inumwj472S9r4" => false,
310
+ # "6LuN9FCkKOj5PcnpouEgny" => true,
311
+ # "69GGBxA162lTqCwzJG5jLp" => false
312
+ # }
313
+ ```
314
+
315
+ #### See all followed artists\*
316
+
317
+ ```ruby
318
+ @sdk.me.following(5) # => [#<Spotify::SDK::Artist...>, ...]
319
+ @sdk.me.following(5).size # => 5
320
+ @sdk.me.following(50) # => [#<Spotify::SDK::Artist...>, ...]
321
+ @sdk.me.following(50).size # => 50
322
+ ```
323
+
324
+
325
+ <small><i>\* Requires specific user permissions/scopes. See [Authorization Scopes] for more information.</i></small>
326
+
327
+ ## Contributing
328
+
329
+ On the website, we have [a full guide on contributing][contributing] for beginners.
330
+
331
+ ### Community Guidelines
332
+
333
+ Bug reports and pull requests are welcome on GitHub at https://github.com/bih/spotify-ruby. This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the [Contributor Covenant] code of conduct.
334
+
335
+ ### Code of Conduct
336
+
337
+ Everyone interacting with this project's codebases, issue trackers, discussions, chat rooms, and mailing lists is required to follow the [Code of Conduct].
338
+
339
+ Whilst we try to always assume good intentions, any clear violations or bad actors will be warned and subsequently banned from this project indefinitely.
340
+
341
+ ### Getting Started
342
+
343
+ Firstly, you'll need Git and Ruby installed. You can then install the dependencies as following:
344
+
345
+ ```bash
346
+ $ git clone ssh://git@github.com/bih/spotify-ruby.git
347
+ $ bin/setup
348
+ ```
349
+
350
+ You can run `rake ci` to validate your Ruby syntax, our RSpec tests, and code coverage.
351
+
352
+ For local development, you can run `bin/console` for an interactive prompt for experimentation.
353
+
354
+ ### Releasing a Change
355
+
356
+ - To install this gem onto your local machine, run `bundle exec rake install`.
357
+ - Ensure versions are in line with the [Semantic Versioning] convention.
358
+ - To release a new version:
359
+ - Update the version number in `lib/spotify/version.rb`
360
+ - Run `bundle exec rake release` (which will create a git tag for the version)
361
+ - Push git commits and tags
362
+ - Push the `.gem` file to [rubygems.org].
363
+
364
+ ## License
365
+
366
+ The gem is available as open source under the terms of the [MIT License].
367
+
368
+ [Spotify]: https://developer.spotify.com
369
+ [Spotify Connect]: https://www.spotify.com/connect/
370
+ [developer.spotify.com]: https://developer.spotify.com
371
+ [Accounts API]: https://developer.spotify.com/documentation/general/guides/authorization-guide/
372
+ [Authorization Scopes]: https://developer.spotify.com/documentation/general/guides/scopes/
373
+
374
+ [Website]: https://bih.github.io/spotify-ruby
375
+ [Contributing]: https://bih.github.io/spotify-ruby/documentation/contributing/
376
+ [SDK Reference]: http://www.rubydoc.info/github/bih/spotify-ruby
377
+ [Code of Conduct]: https://github.com/bih/spotify-ruby/blob/master/CODE_OF_CONDUCT.md
378
+ [Contributor Covenant]: http://contributor-covenant.org
379
+ [Semantic Versioning]: https://semver.org/spec/v2.0.0.html
380
+
381
+ [Build Status]: https://travis-ci.org/bih/spotify-ruby
382
+ [Maintainability]: https://codeclimate.com/github/bih/spotify-ruby/maintainability
383
+ [Test Coverage]: https://codeclimate.com/github/bih/spotify-ruby/test_coverage
384
+ [Gem Version]: https://badge.fury.io/rb/spotify-ruby
385
+ [Code Triagers Badge]: https://www.codetriage.com/bih/spotify-ruby
386
+ [MIT License]: http://opensource.org/licenses/MIT
387
+ [rubygems.org]: https://rubygems.org
388
+ <!-- prettier-ignore-end -->
data/Rakefile ADDED
@@ -0,0 +1,23 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "bundler/gem_tasks"
4
+ require "rspec/core/rake_task"
5
+ require "rubocop/rake_task"
6
+ require "yard"
7
+
8
+ # RSpec
9
+ # For testing the Spotify Ruby project.
10
+ RSpec::Core::RakeTask.new(:spec)
11
+
12
+ # Rubocop
13
+ # Making sure our code is linted.
14
+ RuboCop::RakeTask.new
15
+
16
+ # YARD
17
+ # Making all of the code documentable.
18
+ YARD::Rake::YardocTask.new do |t|
19
+ t.files = ["lib/**/*.rb"]
20
+ end
21
+
22
+ task default: :spec
23
+ task ci: %i[spec rubocop]
data/lib/spotify.rb ADDED
@@ -0,0 +1,17 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "httparty"
4
+
5
+ require "active_support"
6
+ require "active_support/core_ext"
7
+
8
+ require "spotify/version"
9
+ require "spotify/accounts"
10
+ require "spotify/accounts/session"
11
+ require "spotify/sdk"
12
+
13
+ ##
14
+ # The declaration for the Spotify namespace.
15
+ #
16
+ module Spotify
17
+ end