simplespotify 0.0.1
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/.gitignore +10 -0
- data/.rspec +2 -0
- data/.travis.yml +3 -0
- data/Gemfile +4 -0
- data/LICENSE.md +17 -0
- data/Rakefile +3 -0
- data/bin/console +14 -0
- data/bin/setup +7 -0
- data/lib/simplespotify/actions/albums.rb +30 -0
- data/lib/simplespotify/actions/artists.rb +47 -0
- data/lib/simplespotify/actions/browse.rb +74 -0
- data/lib/simplespotify/actions/playlists.rb +187 -0
- data/lib/simplespotify/actions/tracks.rb +67 -0
- data/lib/simplespotify/actions/users.rb +68 -0
- data/lib/simplespotify/authorization.rb +91 -0
- data/lib/simplespotify/client.rb +76 -0
- data/lib/simplespotify/constants.rb +14 -0
- data/lib/simplespotify/errors.rb +56 -0
- data/lib/simplespotify/models/album.rb +27 -0
- data/lib/simplespotify/models/artist.rb +42 -0
- data/lib/simplespotify/models/category.rb +19 -0
- data/lib/simplespotify/models/collection.rb +52 -0
- data/lib/simplespotify/models/image.rb +16 -0
- data/lib/simplespotify/models/playlist.rb +94 -0
- data/lib/simplespotify/models/track.rb +31 -0
- data/lib/simplespotify/models/user.rb +91 -0
- data/lib/simplespotify/request.rb +54 -0
- data/lib/simplespotify/resource/class_methods.rb +48 -0
- data/lib/simplespotify/resource/instance_methods.rb +102 -0
- data/lib/simplespotify/resource/resource.rb +14 -0
- data/lib/simplespotify/response.rb +22 -0
- data/lib/simplespotify/version.rb +3 -0
- data/lib/simplespotify.rb +72 -0
- data/readme.md +71 -0
- data/simplespotify.gemspec +26 -0
- metadata +122 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: f4e69e9cf083380d99cf868d5c0a923e6317c96e
|
4
|
+
data.tar.gz: 5449320aa6f300cdccb61c8bb87a55e9c1eaf769
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: aa3794582c59de6c88cf09b043aef105715838cd0624fb2db0a1a2a893e3c4956d384f049abb058440436262ab2a2a681c6fe09361bbaf204cb2328f8eb6407c
|
7
|
+
data.tar.gz: 672fc08dc3ddbfebd102f9b416e835f238e86cb182a38a455fc642cf5539053987147cbbfc614b95b85845d865c0578ef77c93147a437219fed518796441f74d
|
data/.gitignore
ADDED
data/.rspec
ADDED
data/.travis.yml
ADDED
data/Gemfile
ADDED
data/LICENSE.md
ADDED
@@ -0,0 +1,17 @@
|
|
1
|
+
LICENCIA PATITO
|
2
|
+
Versión 0.0.1; Septiembre, 2014
|
3
|
+
|
4
|
+
Copyright (c) 2015, Roberto Hidalgo, Partido Surrealista Mexicano
|
5
|
+
Todos los derechos reservados.
|
6
|
+
|
7
|
+
La redistribución y uso como código fuente y/u objeto, con o sin modificaciones, está permitida siempre y cuando todas las siguientes condiciones sean respetadas:
|
8
|
+
|
9
|
+
* La redistribución del código fuente debe mantener la nota de copyright antes mencionada, esta lista de condiciones y la renuncia de responsabilidades que acompaña esta licencia.
|
10
|
+
La redistribución del código objeto debe mantener la nota de copyright antes mencionada, esta lista de condiciones y la renuncia de responsabilidades que acompaña esta licencia en la documentación y en cualquier otro material que se ofrezca con el código objeto.
|
11
|
+
* El nombre "SimpleSpotify", ni el nombre de loas colaboradoreas originales podrá ser usado para promocionar o endosar productos derivados de este software sin un consentimiento previo por escrito de los mismos.
|
12
|
+
* Todo uso de este código fuente y archivos relacionados, en su conjunto o de manera individual, así como el material publicitario que mencione las funciones del mismo deberá incluir la leyenda: "Este producto incluye software desarrollado por el Roberto Hidalgo, el Partido Surrealista Mexicano y Colaboradoreas", así como un enlace a esta licencia, y deberá indicar si se han hecho cambios al mismo.
|
13
|
+
* Cualquier uso o implementación de este código fuente y archivos relacionados, en su conjunto o de manera individual, deberá extender los mismos derechos y obligaciones que menciona esta licencia.
|
14
|
+
* Se prohibe el uso de este código cuándo el uso mismo incite o resulte en la discriminación de cualquier individuo o grupo de individuos, en función de su género, orientación sexual, educación y/o poder adquisitivo.
|
15
|
+
* El uso de este código sugiere, más no exige, a los usuarioas del mismo a invitar al Partido Surrealista Mexicano y a cada uno de los Colaboradoreas unos mezcales ó bebidas no-alcoholicas de su elección, como muestra de compañerismo y buena voluntad.
|
16
|
+
|
17
|
+
Este software se ofrece por los titulares de derechos de autor y colaboradores "tal cual", y cualquier garantía explícita o implícita, por ejemplo, de manera enunciativa más no limitativa, la garantía implícita de comercialización y aptitud para un propósito determinado son rechazadas. Bajo ninguna circunstancia serán responsables los titulares de derechos de autor ni colaboradores por cualquier daño directo, indirecto, incidental, especial, ejemplar o consecuente —incluyendo, pero no limitado a, la adquisición de bienes o servicios; la pérdida uso, datos o beneficios; o interrupción de la actividad empresarial—, o por cualquier teoría de responsabilidad estricta ó agravio (incluyendo negligencia, o cualquier otra causa) que surja de la posibilidad de tales daños.
|
data/Rakefile
ADDED
data/bin/console
ADDED
@@ -0,0 +1,14 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require "bundler/setup"
|
4
|
+
require "spotify"
|
5
|
+
|
6
|
+
# You can add fixtures and/or initialization code here to make experimenting
|
7
|
+
# with your gem easier. You can also use a different console, if you like.
|
8
|
+
|
9
|
+
# (If you use this, don't forget to add pry to your Gemfile!)
|
10
|
+
# require "pry"
|
11
|
+
# Pry.start
|
12
|
+
|
13
|
+
require "irb"
|
14
|
+
IRB.start
|
data/bin/setup
ADDED
@@ -0,0 +1,30 @@
|
|
1
|
+
module SimpleSpotify
|
2
|
+
module Actions
|
3
|
+
module Albums
|
4
|
+
|
5
|
+
def album album, market: nil
|
6
|
+
response = get "albums/#{id_for(album)}", options_with_market(market, {})
|
7
|
+
Model::Album.new(response.body)
|
8
|
+
end
|
9
|
+
|
10
|
+
|
11
|
+
def albums *albums, market: nil
|
12
|
+
albums = albums.map {|a|
|
13
|
+
id_for(a)
|
14
|
+
}.join(',')
|
15
|
+
|
16
|
+
response = get "albums", options_with_market(market, {ids: albums})
|
17
|
+
Model::Collection.of(:albums, response.body)
|
18
|
+
end
|
19
|
+
|
20
|
+
|
21
|
+
def album_tracks album, limit: 20, offset: 0, market: nil
|
22
|
+
options = options_with_market(market, {limit: limit, offset: offset})
|
23
|
+
response = get "albums/#{id_for(album)}/tracks", options
|
24
|
+
Model::Collection.of(:tracks, response.body)
|
25
|
+
end
|
26
|
+
|
27
|
+
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
@@ -0,0 +1,47 @@
|
|
1
|
+
module SimpleSpotify
|
2
|
+
module Actions
|
3
|
+
module Artists
|
4
|
+
|
5
|
+
|
6
|
+
def artist artist
|
7
|
+
response = get "artist/#{id_for(artist)}"
|
8
|
+
Model::Artist.new(response.body)
|
9
|
+
end
|
10
|
+
|
11
|
+
|
12
|
+
def artists *artists
|
13
|
+
artists = artists.map {|a|
|
14
|
+
id_for(a)
|
15
|
+
}.join(',')
|
16
|
+
|
17
|
+
response = get "artists", {ids: artists}
|
18
|
+
Model::Collection.of(:artists, response.body)
|
19
|
+
end
|
20
|
+
|
21
|
+
|
22
|
+
def artist_albums artist, album_type: nil, market: nil, limit: 20, offset: 0
|
23
|
+
options = {album_type: album_type, limit: limit, offset: offset}
|
24
|
+
response = get "artists/#{id_for(artist)}/albums", options_with_market(market, options)
|
25
|
+
Model::Collection.of(:artists, response.body)
|
26
|
+
end
|
27
|
+
|
28
|
+
|
29
|
+
def top_tracks artist, market=nil
|
30
|
+
id = id_for(artist)
|
31
|
+
market = market || @market
|
32
|
+
raise "Market required for top tracks" unless market
|
33
|
+
|
34
|
+
response = get "artists/#{id}/top-tracks", {country: market}
|
35
|
+
Model::Collection.of(:tracks, response.body)
|
36
|
+
end
|
37
|
+
|
38
|
+
|
39
|
+
def related_artists artist
|
40
|
+
response = get "artists/#{id_for(artist)}/related-artists"
|
41
|
+
Model::Collection.of(:artists, response.body)
|
42
|
+
end
|
43
|
+
|
44
|
+
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
@@ -0,0 +1,74 @@
|
|
1
|
+
module SimpleSpotify
|
2
|
+
module Actions
|
3
|
+
module Browse
|
4
|
+
|
5
|
+
|
6
|
+
def featured_playlists locale: nil, country: nil, timestamp: nil, limit: 20, offset: 0
|
7
|
+
locale ||= ENV['LANG'].split('.').first if ENV['LANG']
|
8
|
+
timestamp = timestamp.to_time if timestamp.is_a Date
|
9
|
+
timestamp = timestamp.iso8601 if timestamp.is_a? Time
|
10
|
+
|
11
|
+
options = {
|
12
|
+
locale: locale,
|
13
|
+
country: country || @market,
|
14
|
+
timestamp: timestamp,
|
15
|
+
limit: limit,
|
16
|
+
offset: offset
|
17
|
+
}.reject {|k,v| v.nil? || v==''}.to_h
|
18
|
+
|
19
|
+
response = get "browse/featured-playlists", options
|
20
|
+
Model::Collection.of(:playlists, response.body[:playlists])
|
21
|
+
end
|
22
|
+
|
23
|
+
|
24
|
+
def new_releases country: nil, limit: 20, offset: 0
|
25
|
+
options = {limit: limit, offset: offset}
|
26
|
+
market = country || @market
|
27
|
+
options[:country] = market if market
|
28
|
+
|
29
|
+
response = get "browse/new-releases", options
|
30
|
+
Model::Collection.of(:albums, response.body[:albums])
|
31
|
+
end
|
32
|
+
|
33
|
+
|
34
|
+
def categories country: nil, locale: nil, limit: 20, offset: 0
|
35
|
+
options = {limit: limit, offset: offset}
|
36
|
+
|
37
|
+
market = country || @market
|
38
|
+
options[:country] = market if market
|
39
|
+
|
40
|
+
locale ||= ENV['LANG'].split('.').first if ENV['LANG']
|
41
|
+
options[:locale] = locale if locale
|
42
|
+
|
43
|
+
response = get "browse/categories", options
|
44
|
+
Model::Collection.of(Model::Category, response.body[:categories])
|
45
|
+
end
|
46
|
+
|
47
|
+
|
48
|
+
def category category, country: nil, locale: nil
|
49
|
+
options = {}
|
50
|
+
market = country || @market
|
51
|
+
options[:country] = market if market
|
52
|
+
|
53
|
+
locale ||= ENV['LANG'].split('.').first if ENV['LANG']
|
54
|
+
options[:locale] = locale if locale
|
55
|
+
|
56
|
+
response = get "browse/categories/#{id_for(category)}"
|
57
|
+
Model::Category.new(response)
|
58
|
+
end
|
59
|
+
|
60
|
+
|
61
|
+
def category_playlists category, country: nil, limit: 20, offset: 0
|
62
|
+
options = {limit: limit, offset: offset}
|
63
|
+
|
64
|
+
market = country || @market
|
65
|
+
options[:country] = market if market
|
66
|
+
|
67
|
+
response = get "browse/categories/#{id_for(category)}/playlists", options
|
68
|
+
Model::Collection.of(:playlists, response.body[:playlists])
|
69
|
+
end
|
70
|
+
|
71
|
+
|
72
|
+
end
|
73
|
+
end
|
74
|
+
end
|
@@ -0,0 +1,187 @@
|
|
1
|
+
module SimpleSpotify
|
2
|
+
module Actions
|
3
|
+
module Playlists
|
4
|
+
|
5
|
+
|
6
|
+
def playlist owner, playlist=nil, fields:{}, market: nil
|
7
|
+
fields = fields.join(',') if fields.is_a? Array
|
8
|
+
options = {
|
9
|
+
fields: fields
|
10
|
+
}
|
11
|
+
|
12
|
+
if owner.is_a? Model::Playlist
|
13
|
+
playlist = owner
|
14
|
+
owner = playlist.owner
|
15
|
+
end
|
16
|
+
|
17
|
+
res = get "users/#{id_for(owner)}/playlists/#{id_for(playlist)}", options_with_market(market, options)
|
18
|
+
Model::Playlist.new(res.body)
|
19
|
+
end
|
20
|
+
|
21
|
+
|
22
|
+
def playlists owner, limit: 20, offset: 0
|
23
|
+
Model::Collection.for(:playlists, get("users/#{id_for(owner)}/playlists", {limit: limit, offset: offset}))
|
24
|
+
end
|
25
|
+
|
26
|
+
|
27
|
+
#--------------
|
28
|
+
# Creation/Update
|
29
|
+
#--------------
|
30
|
+
def playlist_create user, name, public: true
|
31
|
+
res = post "users/#{id_for(user)}/playlists", {name: name, public: public}
|
32
|
+
Model::Playlist.new(res.body)
|
33
|
+
end
|
34
|
+
|
35
|
+
|
36
|
+
def playlist_change_details owner, playlist=nil, name: nil, public: nil
|
37
|
+
data = {}
|
38
|
+
data[:name] = name if name
|
39
|
+
data[:public] = public if public
|
40
|
+
|
41
|
+
if owner.is_a? Model::Playlist
|
42
|
+
playlist = owner
|
43
|
+
owner = playlist.owner
|
44
|
+
end
|
45
|
+
|
46
|
+
put "users/#{id_for(owner)}/playlists/#{id_for(playlist)}", data
|
47
|
+
end
|
48
|
+
|
49
|
+
|
50
|
+
#--------------
|
51
|
+
# Tracks
|
52
|
+
#--------------
|
53
|
+
def playlist_tracks owner, playlist=nil, fields: {}, limit: 20, offset: 0, market: nil
|
54
|
+
fields = fields.join(',') if fields.is_a? Array
|
55
|
+
options = {
|
56
|
+
fields: fields,
|
57
|
+
limit: limit,
|
58
|
+
offset: offset
|
59
|
+
}
|
60
|
+
|
61
|
+
if owner.is_a? Model::Playlist
|
62
|
+
playlist = owner
|
63
|
+
owner = playlist.owner
|
64
|
+
end
|
65
|
+
|
66
|
+
res = get "users/#{id_for(owner)}/playlists/#{id_for(playlist)}/tracks", options_with_market(market, options)
|
67
|
+
Model::Playlist.new(res.body)
|
68
|
+
end
|
69
|
+
|
70
|
+
|
71
|
+
def playlist_tracks_add owner, playlist=nil, tracks: [], position: nil
|
72
|
+
if owner.is_a? Model::Playlist
|
73
|
+
playlist = owner
|
74
|
+
owner = playlist.owner
|
75
|
+
end
|
76
|
+
|
77
|
+
tracks = case tracks
|
78
|
+
when Array then tracks.map {|t|
|
79
|
+
t.is_a?(Model::Track) ? t.id : t
|
80
|
+
}
|
81
|
+
when String then tracks.split(',')
|
82
|
+
end.map {|t| "spotify:track:#{t.split(':').last}" }
|
83
|
+
|
84
|
+
|
85
|
+
data = {}
|
86
|
+
data[:position] = position if position
|
87
|
+
data[:uris] = tracks
|
88
|
+
|
89
|
+
res = post "users/#{id_for(owner)}/playlists/#{id_for(playlist)}/tracks", data
|
90
|
+
res.body[:snapshot_id]
|
91
|
+
end
|
92
|
+
|
93
|
+
|
94
|
+
def playlist_tracks_remove owner, playlist=nil, tracks: nil, positions: nil, snapshot_id: nil
|
95
|
+
if owner.is_a? Model::Playlist
|
96
|
+
playlist = owner
|
97
|
+
owner = playlist.owner
|
98
|
+
end
|
99
|
+
|
100
|
+
data = {}
|
101
|
+
tracks = case tracks
|
102
|
+
when Array then tracks.map {|t|
|
103
|
+
case t
|
104
|
+
when Model::Track then {uri: t.uri}
|
105
|
+
when String then {uri: "spotify:track:#{t.split(':').last}"}
|
106
|
+
when Hash
|
107
|
+
t[:positions] = [t[:positions]].flatten if t[:positions]
|
108
|
+
t[:uri] = "spotify:track:#{t[:uri].split(':').last}"
|
109
|
+
end
|
110
|
+
}
|
111
|
+
when String then tracks.split(',')
|
112
|
+
else nil
|
113
|
+
end
|
114
|
+
|
115
|
+
data[:tracks] = tracks if tracks
|
116
|
+
data[:positions] = [positions].flatten if positions
|
117
|
+
data[:snapshot_id] = snapshot_id if snapshot_id
|
118
|
+
|
119
|
+
puts data
|
120
|
+
|
121
|
+
res = delete "users/#{id_for(owner)}/playlists/#{id_for(playlist)}/tracks", data
|
122
|
+
res.body[:snapshot_id]
|
123
|
+
end
|
124
|
+
|
125
|
+
|
126
|
+
def playlist_tracks_reorder owner, playlist=nil, start: 0, length: 1, before: nil, snapshot_id: nil
|
127
|
+
if owner.is_a? Model::Playlist
|
128
|
+
playlist = owner
|
129
|
+
owner = playlist.owner
|
130
|
+
end
|
131
|
+
|
132
|
+
raise "Must set `before` option when reordering playlist tracks" unless before
|
133
|
+
|
134
|
+
data = {
|
135
|
+
range_start: start,
|
136
|
+
range_length: length,
|
137
|
+
insert_before: before
|
138
|
+
}
|
139
|
+
data[:snapshot_id] = snapshot_id unless snapshot_id.nil?
|
140
|
+
|
141
|
+
res = put "users/#{id_for(owner)}/playlists/#{id_for(playlist)}/tracks", data
|
142
|
+
res.body[:snapshot_id]
|
143
|
+
end
|
144
|
+
|
145
|
+
|
146
|
+
def playlist_tracks_replace owner, playlist=nil, tracks: []
|
147
|
+
if owner.is_a? Model::Playlist
|
148
|
+
playlist = owner
|
149
|
+
owner = playlist.owner
|
150
|
+
end
|
151
|
+
|
152
|
+
data[:uris] = tracks.map { |t|
|
153
|
+
case t
|
154
|
+
when Model::Track then t.uri
|
155
|
+
when String then "spotify:track:#{t.split(':').last}"
|
156
|
+
end
|
157
|
+
}
|
158
|
+
|
159
|
+
res = put "users/#{id_for(owner)}/playlists/#{id_for(playlist)}/tracks", data
|
160
|
+
res.body[:snapshot_id]
|
161
|
+
end
|
162
|
+
|
163
|
+
|
164
|
+
|
165
|
+
#--------------
|
166
|
+
# Follows
|
167
|
+
#--------------
|
168
|
+
def playlist_follow owner, playlist=nil, public: true
|
169
|
+
if owner.is_a? Model::Playlist
|
170
|
+
playlist = owner
|
171
|
+
owner = playlist.owner
|
172
|
+
end
|
173
|
+
put "users/#{id_for(owner)}/playlists/#{id_for(playlist)}/followers", {public: public}
|
174
|
+
end
|
175
|
+
|
176
|
+
|
177
|
+
def playlist_unfollow owner, playlist=nil
|
178
|
+
if owner.is_a? Model::Playlist
|
179
|
+
playlist = owner
|
180
|
+
owner = playlist.owner
|
181
|
+
end
|
182
|
+
delete "users/#{id_for(owner)}/playlists/#{id_for(playlist)}/followers"
|
183
|
+
end
|
184
|
+
|
185
|
+
end
|
186
|
+
end
|
187
|
+
end
|
@@ -0,0 +1,67 @@
|
|
1
|
+
module SimpleSpotify
|
2
|
+
module Actions
|
3
|
+
module Tracks
|
4
|
+
|
5
|
+
def track id, market: nil
|
6
|
+
res = get "tracks/#{id_for(id)}", options_with_market(market)
|
7
|
+
Model::Track.new(res.body)
|
8
|
+
end
|
9
|
+
|
10
|
+
|
11
|
+
def tracks ids, market: nil
|
12
|
+
if ids.is_a? Array
|
13
|
+
ids.map { |i|
|
14
|
+
id_for(i)
|
15
|
+
}.join(',')
|
16
|
+
end
|
17
|
+
|
18
|
+
Model::Collection.of(:tracks, response.body)
|
19
|
+
end
|
20
|
+
|
21
|
+
|
22
|
+
#--------------
|
23
|
+
# Saved tracks
|
24
|
+
#--------------
|
25
|
+
def saved_tracks limit: 20, offset: 0, market: nil
|
26
|
+
response = get "me/tracks", options_with_market(market, {limit: limit, offset: offset})
|
27
|
+
Model::Collection.of(Model::PlaylistTrack, response.body)
|
28
|
+
end
|
29
|
+
|
30
|
+
|
31
|
+
def saved_tracks_include? ids
|
32
|
+
if ids.is_a? Array
|
33
|
+
ids.map { |i|
|
34
|
+
i.is_a?(Resource) ? i.id : i;
|
35
|
+
}.join(',')
|
36
|
+
end
|
37
|
+
|
38
|
+
res = get "me/tracks/contains", {ids: ids}
|
39
|
+
ids.zip(res.body).to_h
|
40
|
+
end
|
41
|
+
|
42
|
+
|
43
|
+
def save_tracks ids
|
44
|
+
if ids.is_a? Array
|
45
|
+
ids.map { |i|
|
46
|
+
i.is_a?(Resource) ? i.id : i;
|
47
|
+
}.join(',')
|
48
|
+
end
|
49
|
+
|
50
|
+
put "me/tracks", {ids: ids}
|
51
|
+
end
|
52
|
+
|
53
|
+
|
54
|
+
def remove_tracks ids
|
55
|
+
if ids.is_a? Array
|
56
|
+
ids.map { |i|
|
57
|
+
i.is_a?(Resource) ? i.id : i;
|
58
|
+
}.join(',')
|
59
|
+
end
|
60
|
+
|
61
|
+
delete "me/tracks", {ids: ids}
|
62
|
+
end
|
63
|
+
|
64
|
+
|
65
|
+
end
|
66
|
+
end
|
67
|
+
end
|
@@ -0,0 +1,68 @@
|
|
1
|
+
module SimpleSpotify
|
2
|
+
module Actions
|
3
|
+
module Users
|
4
|
+
|
5
|
+
def me
|
6
|
+
Model::User.new (get :me).body
|
7
|
+
end
|
8
|
+
|
9
|
+
|
10
|
+
def user id
|
11
|
+
Model::User.new (get "user/#{id}").body
|
12
|
+
end
|
13
|
+
|
14
|
+
|
15
|
+
#--------------
|
16
|
+
# Follows
|
17
|
+
#--------------
|
18
|
+
def user_follow type, ids
|
19
|
+
if ids.is_a? Array
|
20
|
+
ids.map { |i|
|
21
|
+
i.is_a?(Resource) ? i.id : i;
|
22
|
+
}.join(',')
|
23
|
+
end
|
24
|
+
|
25
|
+
req = SimpleSpotify::Request.new("me/following", {
|
26
|
+
json: true,
|
27
|
+
query: {type: type},
|
28
|
+
data: {ids: ids},
|
29
|
+
method: :put
|
30
|
+
})
|
31
|
+
|
32
|
+
put req
|
33
|
+
end
|
34
|
+
|
35
|
+
|
36
|
+
def user_unfollow type, ids
|
37
|
+
if ids.is_a? Array
|
38
|
+
ids.map { |i|
|
39
|
+
i.is_a?(Resource) ? i.id : i;
|
40
|
+
}.join(',')
|
41
|
+
end
|
42
|
+
|
43
|
+
req = SimpleSpotify::Request.new("me/following", {
|
44
|
+
json: true,
|
45
|
+
query: {type: type},
|
46
|
+
data: {ids: ids},
|
47
|
+
method: :delete
|
48
|
+
})
|
49
|
+
|
50
|
+
delete req
|
51
|
+
end
|
52
|
+
|
53
|
+
|
54
|
+
def user_following type, ids
|
55
|
+
if ids.is_a? Array
|
56
|
+
ids.map { |i|
|
57
|
+
i.is_a?(Resource) ? i.id : i;
|
58
|
+
}.join(',')
|
59
|
+
end
|
60
|
+
|
61
|
+
res = get "me/following/contains", {ids: ids, type: type}
|
62
|
+
ids.zip(res.body).to_h
|
63
|
+
end
|
64
|
+
|
65
|
+
|
66
|
+
end
|
67
|
+
end
|
68
|
+
end
|
@@ -0,0 +1,91 @@
|
|
1
|
+
module SimpleSpotify
|
2
|
+
class Authorization
|
3
|
+
|
4
|
+
attr_accessor :access_token, :refresh_token
|
5
|
+
attr_reader :client_id
|
6
|
+
|
7
|
+
def self.login_uri redirect, client, state: nil, scope: nil, dialog: false
|
8
|
+
params = {
|
9
|
+
client_id: client.to_h[:client_id],
|
10
|
+
response_type: 'code',
|
11
|
+
redirect_uri: redirect,
|
12
|
+
}
|
13
|
+
|
14
|
+
params[:state] = state unless state.nil?
|
15
|
+
if scope
|
16
|
+
scope = scope.join(' ') if scope.is_a? Array
|
17
|
+
params[:scope] = scope
|
18
|
+
end
|
19
|
+
params[:show_dialog] = dialog.to_s
|
20
|
+
|
21
|
+
params_qs = params.map {|k,v|
|
22
|
+
"#{k}=#{URI::encode(v)}"
|
23
|
+
}.join('&')
|
24
|
+
return SimpleSpotify::AUTHORIZATION_URL + '?' + params_qs
|
25
|
+
end
|
26
|
+
|
27
|
+
|
28
|
+
def self.from_code code, client: {}, redirect: nil
|
29
|
+
params = {
|
30
|
+
grant_type: 'authorization_code',
|
31
|
+
redirect_uri: redirect,
|
32
|
+
code: code,
|
33
|
+
}.merge(client.to_h)
|
34
|
+
|
35
|
+
response = HTTParty.post SimpleSpotify::TOKEN_URL, query: params
|
36
|
+
|
37
|
+
body = JSON.parse(response.body, symbolize_names: true)
|
38
|
+
if response.code != 200
|
39
|
+
raise SimpleSpotify::Error::AuthorizationError.new(body)
|
40
|
+
end
|
41
|
+
|
42
|
+
return Authorization.new(body)
|
43
|
+
end
|
44
|
+
|
45
|
+
|
46
|
+
def initialize access_token: nil, refresh_token:nil, client: {}, token_type: nil, expires_in: nil
|
47
|
+
@access_token = access_token
|
48
|
+
@refresh_token = refresh_token
|
49
|
+
@client = client.to_h
|
50
|
+
@client_id = @client[:client_id]
|
51
|
+
end
|
52
|
+
|
53
|
+
|
54
|
+
def headers
|
55
|
+
{'Authorization' => "Bearer #{@access_token}"}
|
56
|
+
end
|
57
|
+
|
58
|
+
|
59
|
+
def refresh!
|
60
|
+
params = {
|
61
|
+
grant_type: 'refresh_token',
|
62
|
+
refresh_token: @refresh_token
|
63
|
+
}.merge(@client)
|
64
|
+
|
65
|
+
response = HTTParty.post SimpleSpotify::TOKEN_URL, query: params
|
66
|
+
|
67
|
+
body = JSON.parse(response.body, symbolize_names: true)
|
68
|
+
if response.code != 200
|
69
|
+
raise SimpleSpotify::Error::AuthorizationError.new(body)
|
70
|
+
end
|
71
|
+
|
72
|
+
@access_token = body[:access_token]
|
73
|
+
@callback.call(self) if @callback
|
74
|
+
end
|
75
|
+
|
76
|
+
|
77
|
+
def on_refresh &block
|
78
|
+
@callback = block
|
79
|
+
end
|
80
|
+
|
81
|
+
|
82
|
+
def to_h
|
83
|
+
{
|
84
|
+
access_token: access_token,
|
85
|
+
refresh_token: refresh_token
|
86
|
+
}
|
87
|
+
end
|
88
|
+
|
89
|
+
|
90
|
+
end
|
91
|
+
end
|