jberkel-spotify-api 0.0.3 → 0.0.4
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/README.md +1 -1
- data/VERSION.yml +1 -1
- data/bin/spotify-api-server +15 -2
- data/examples/create_playlist.rb +1 -1
- data/examples/modify_playlist.rb +32 -0
- data/lib/jotify.rb +21 -2
- data/lib/jotify/api.rb +28 -12
- data/lib/jotify/media.rb +4 -0
- data/spec/jotify/api_spec.rb +35 -14
- data/spec/jotify_spec.rb +29 -2
- data/spotify-api.gemspec +4 -2
- metadata +4 -2
data/README.md
CHANGED
@@ -14,7 +14,7 @@ At the moment the following features are implemented:
|
|
14
14
|
* list user's playlists [GET /playlists]
|
15
15
|
* get shared playlist [GET /playlist/id]
|
16
16
|
* create new playlist [POST /playlists]
|
17
|
-
*
|
17
|
+
* update playlists [PUT /playlists/id]
|
18
18
|
|
19
19
|
## Installation
|
20
20
|
|
data/VERSION.yml
CHANGED
data/bin/spotify-api-server
CHANGED
@@ -1,5 +1,5 @@
|
|
1
|
-
#!/usr/bin/env jruby
|
2
|
-
$LOAD_PATH.unshift(File.
|
1
|
+
#!/usr/bin/env jruby #--jdb -J-sourcepath -J/Users/jan/projects/jotify/src
|
2
|
+
$LOAD_PATH.unshift(File.expand_path(File.dirname(__FILE__) + '/../lib'))
|
3
3
|
|
4
4
|
require 'rubygems'
|
5
5
|
require 'jotify'
|
@@ -23,5 +23,18 @@ while arg = ARGV.shift do
|
|
23
23
|
end
|
24
24
|
end
|
25
25
|
|
26
|
+
# Taken mostly from
|
27
|
+
# http://groups.google.com/group/sinatrarb/t/a5cfc2b77a013a86
|
28
|
+
class Sinatra::Reloader < Rack::Reloader
|
29
|
+
def safe_load(file, mtime, stderr = $stderr)
|
30
|
+
# ::Sinatra::Application.reset!
|
31
|
+
# stderr.puts "#{self.class}: reseting routes"
|
32
|
+
super
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
26
36
|
#Sinatra::Application.set :environment, :production
|
37
|
+
Sinatra::Application.configure(:development) do |app|
|
38
|
+
app.use Sinatra::Reloader
|
39
|
+
end
|
27
40
|
Sinatra::Application.run! :port=> (port || DEFAULT_PORT).to_i
|
data/examples/create_playlist.rb
CHANGED
@@ -7,7 +7,7 @@ require 'pp'
|
|
7
7
|
|
8
8
|
puts "creating a new playlist"
|
9
9
|
resp = RestClient.post('http://localhost:3000/playlists', {
|
10
|
-
"name"=>'my shiny playlist',
|
10
|
+
"name"=>'my shiny playlist', "collaborative"=>false,
|
11
11
|
"tracks" => [ {'id'=>'6qHiOf1BFCQIzAjJsRbMfY'}, {'id'=>'1VaucR6Bsks5Q9bYBsXvuF'} ]
|
12
12
|
}.to_json)
|
13
13
|
|
@@ -0,0 +1,32 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require 'rubygems'
|
4
|
+
require 'rest_client'
|
5
|
+
require 'json'
|
6
|
+
require 'pp'
|
7
|
+
|
8
|
+
#spotify:user:jberkel:playlist:51QyZ8kHWdx1wuetLfs571
|
9
|
+
#spotify:user:jberkel:playlist:52vlrAr9RdphpgVtP2SAGP (empty)
|
10
|
+
#spotify:user:jberkel:playlist:5aZg2QhSogW4Ukw7Q6kjRO
|
11
|
+
#spotify:user:jberkel:playlist:1G1BCuefz7bvZdQ5QbGLPR
|
12
|
+
#spotify:user:jberkel:playlist:28C9HrzCMmlSReG4mSQeuQ
|
13
|
+
#spotify:user:jberkel:playlist:4h9wgIOBjlqMoMD0C7LdDs
|
14
|
+
p_id = '4h9wgIOBjlqMoMD0C7LdDs'
|
15
|
+
p_url = "http://localhost:3000/playlists/#{p_id}"
|
16
|
+
puts "getting playlist #{p_id}"
|
17
|
+
resp = RestClient.get p_url
|
18
|
+
playlist = JSON.parse(resp)
|
19
|
+
pp playlist
|
20
|
+
|
21
|
+
|
22
|
+
existing_songs = playlist['result']['tracks'].map { |t| t['id'] }
|
23
|
+
|
24
|
+
|
25
|
+
add_songs = ['1VaucR6Bsks5Q9bYBsXvuF', 'spotify:track:3RIgfgKZm7khbOokcYeFn0']
|
26
|
+
#add_songs = ['spotify:track:2jpVApJaYkYGYRL7WQHnvu']
|
27
|
+
#add_songs = [ 'spotify:track:4hXA0NkPLFf6mXMxzsQicd' ]
|
28
|
+
RestClient.put p_url, {
|
29
|
+
'name' => 'a new name',
|
30
|
+
'collaborative' => false,
|
31
|
+
'tracks' => (existing_songs + add_songs).map { |s| { 'id'=>s } }
|
32
|
+
}.to_json
|
data/lib/jotify.rb
CHANGED
@@ -61,6 +61,8 @@ class Jotify
|
|
61
61
|
end
|
62
62
|
|
63
63
|
def create_playlist(name, collaborative=false)
|
64
|
+
raise ArgumentError, "need name" unless name
|
65
|
+
|
64
66
|
playlist = @jotify.playlistCreate(name, collaborative)
|
65
67
|
return nil unless playlist
|
66
68
|
add_playlist(playlist)
|
@@ -71,10 +73,27 @@ class Jotify
|
|
71
73
|
@jotify.playlistsAddPlaylist(@jotify.playlists, id.is_a?(Media::Playlist) ? id : playlist(id))
|
72
74
|
end
|
73
75
|
|
74
|
-
def
|
76
|
+
def rename_playlist(playlist, name)
|
77
|
+
@jotify.playlistRename(playlist, name)
|
78
|
+
end
|
79
|
+
|
80
|
+
def set_collaborative_flag(playlist, flag)
|
81
|
+
@jotify.playlistSetCollaborative(playlist, flag)
|
82
|
+
end
|
83
|
+
|
84
|
+
def set_tracks_on_playlist(playlist, track_ids)
|
85
|
+
#puts "playlist: checksum #{playlist.getChecksum()}"
|
75
86
|
tracks = Java::JavaUtil::ArrayList.new
|
76
87
|
track_ids.each { |id| tracks.add(Media::Track.new(Jotify.resolve_id(id))) }
|
77
|
-
|
88
|
+
|
89
|
+
# delete old tracks
|
90
|
+
if playlist.tracks.size > 0
|
91
|
+
raise "could not remove tracks" unless @jotify.playlistRemoveTracks(playlist, 0, playlist.tracks.size)
|
92
|
+
end
|
93
|
+
|
94
|
+
return true if track_ids.empty?
|
95
|
+
|
96
|
+
@jotify.playlistAddTracks(playlist, tracks, playlist.tracks.size)
|
78
97
|
end
|
79
98
|
|
80
99
|
def self.resolve_id(id)
|
data/lib/jotify/api.rb
CHANGED
@@ -61,10 +61,12 @@ end
|
|
61
61
|
|
62
62
|
Sinatra::Application.get('/playlists') do
|
63
63
|
content_type :json
|
64
|
-
#playlists = jotify.playlists
|
65
64
|
{
|
66
65
|
'status'=>'OK',
|
67
|
-
'result'=> { 'playlists' => jotify.playlists.map
|
66
|
+
'result'=> { 'playlists' => jotify.playlists.map do |p|
|
67
|
+
p.to_h
|
68
|
+
end.each { |h| h.delete(:tracks) }
|
69
|
+
}
|
68
70
|
}.to_json
|
69
71
|
end
|
70
72
|
|
@@ -84,11 +86,11 @@ Sinatra::Application.post('/playlists') do
|
|
84
86
|
content_type :json
|
85
87
|
body = request.body.read
|
86
88
|
data = JSON.parse(body)
|
87
|
-
playlist = jotify.create_playlist(data['name'], data['collaborative'])
|
89
|
+
playlist = jotify.create_playlist(data['name'], !!data['collaborative'])
|
88
90
|
if playlist
|
89
91
|
if data['tracks']
|
90
92
|
ids = data['tracks'].map { |t| t['id'] }
|
91
|
-
unless jotify.
|
93
|
+
unless jotify.set_tracks_on_playlist(playlist, ids)
|
92
94
|
return 500, 'status' => 'ERROR', 'message' => 'playlist created but tracks could not be added'
|
93
95
|
end
|
94
96
|
end
|
@@ -101,18 +103,32 @@ end
|
|
101
103
|
Sinatra::Application.put('/playlists/:id') do
|
102
104
|
content_type :json
|
103
105
|
playlist = jotify.playlist(params[:id])
|
106
|
+
|
104
107
|
return 404, { 'status' => 'ERROR', 'message' => 'playlist not found' }.to_json unless playlist
|
105
108
|
body = request.body.read
|
106
109
|
data = JSON.parse(body)
|
107
|
-
raise ArgumentError, "invalid format" unless data.is_a?(Hash) && data['tracks'].is_a?(Array)
|
108
|
-
ids = data['tracks'].map { |t| t['id'] }
|
109
|
-
return 200, { 'status' => 'OK', 'message' => 'not modified' }.to_json if ids.empty?
|
110
110
|
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
111
|
+
raise ArgumentError, "invalid format" unless data.is_a?(Hash)
|
112
|
+
|
113
|
+
if data.has_key?('name') && data['name'] != playlist.name
|
114
|
+
unless jotify.rename_playlist(playlist, data['name'])
|
115
|
+
return 500, { 'status' => 'ERROR', 'message' => 'could rename playlist' }.to_json
|
116
|
+
end
|
117
|
+
end
|
118
|
+
|
119
|
+
if data.has_key?('collaborative') && data['collaborative'] != playlist.collaborative?
|
120
|
+
unless jotify.set_collaborative_flag(playlist, data['collaborative'])
|
121
|
+
return 500, { 'status' => 'ERROR', 'message' => 'could not change collaborative flag' }.to_json
|
122
|
+
end
|
123
|
+
end
|
124
|
+
|
125
|
+
if data['tracks'].is_a?(Array)
|
126
|
+
ids = data['tracks'].map { |t| t['id'] }
|
127
|
+
unless jotify.set_tracks_on_playlist(playlist, ids)
|
128
|
+
return 500, { 'status' => 'ERROR', 'message' => 'could update tracks' }.to_json
|
129
|
+
end
|
130
|
+
end
|
131
|
+
return 200, { 'status' => 'OK', 'message' => "update successful" }.to_json
|
116
132
|
end
|
117
133
|
|
118
134
|
|
data/lib/jotify/media.rb
CHANGED
data/spec/jotify/api_spec.rb
CHANGED
@@ -99,7 +99,7 @@ describe 'Api' do
|
|
99
99
|
"id"=>"4d921ebcdd8c80f32ce1ed5acafbb9c8",
|
100
100
|
"url"=>"http://open.spotify.com/user/test/playlist/2mnbxTkghYtlHMdX3jdP9C",
|
101
101
|
"name"=>"my shiny playlist",
|
102
|
-
"
|
102
|
+
"author"=>"test", "revision"=>-1, "collaborative"=>false
|
103
103
|
]
|
104
104
|
}
|
105
105
|
}
|
@@ -134,7 +134,7 @@ describe 'Api' do
|
|
134
134
|
end
|
135
135
|
|
136
136
|
|
137
|
-
describe "create
|
137
|
+
describe "create" do
|
138
138
|
it "should create a playlist when posting to /playlists" do
|
139
139
|
@jotify.should_receive(:create_playlist).with('my shiny playlist', true).and_return(@playlist)
|
140
140
|
post '/playlists', { 'name' => 'my shiny playlist', 'collaborative' => true }.to_json
|
@@ -144,7 +144,7 @@ describe 'Api' do
|
|
144
144
|
|
145
145
|
it "should create a playlist and adding tracks when posting to /playlists" do
|
146
146
|
@jotify.should_receive(:create_playlist).with('my shiny playlist', true).and_return(@playlist)
|
147
|
-
@jotify.should_receive(:
|
147
|
+
@jotify.should_receive(:set_tracks_on_playlist).with(@playlist, ['1','2']).and_return(true)
|
148
148
|
|
149
149
|
post '/playlists', { 'name' => 'my shiny playlist',
|
150
150
|
'collaborative' => true,
|
@@ -153,7 +153,7 @@ describe 'Api' do
|
|
153
153
|
last_response.status.should == 201
|
154
154
|
last_response.headers['Location'].should == 'http://open.spotify.com/user/test/playlist/2mnbxTkghYtlHMdX3jdP9C'
|
155
155
|
end
|
156
|
-
|
156
|
+
|
157
157
|
|
158
158
|
it "should return 500 if playlist could not be created" do
|
159
159
|
@jotify.should_receive(:create_playlist).with('my shiny playlist', true).and_return(nil)
|
@@ -162,15 +162,36 @@ describe 'Api' do
|
|
162
162
|
json_response.should == {"status"=>"ERROR", "message"=>"playlist could not be created"}
|
163
163
|
end
|
164
164
|
|
165
|
+
end
|
165
166
|
|
167
|
+
describe "update" do
|
166
168
|
it "should update playlist when putting to /playlists/id" do
|
167
169
|
@jotify.should_receive(:playlist).with("foo").and_return(@playlist)
|
168
|
-
@jotify.should_receive(:
|
170
|
+
@jotify.should_receive(:set_tracks_on_playlist).with(@playlist, ['1','2']).and_return(true)
|
169
171
|
put '/playlists/foo', { 'tracks' => [ {'id'=>'1' }, { 'id'=>'2' } ] }.to_json
|
170
172
|
last_response.should be_ok
|
171
|
-
json_response.should == {'status'=>'OK', 'message'=>'
|
173
|
+
json_response.should == {'status'=>'OK', 'message'=>'update successful'}
|
174
|
+
end
|
175
|
+
|
176
|
+
it "should change the name of the playlist" do
|
177
|
+
@jotify.should_receive(:playlist).with("foo").and_return(@playlist)
|
178
|
+
@jotify.should_receive(:rename_playlist).with(@playlist, 'new').and_return(true)
|
179
|
+
|
180
|
+
put '/playlists/foo', { 'name' => 'new' }.to_json
|
181
|
+
last_response.should be_ok
|
182
|
+
json_response.should == {'status'=>'OK', 'message'=>'update successful'}
|
172
183
|
end
|
173
184
|
|
185
|
+
it "should change the collaborative flag of the playlist" do
|
186
|
+
@jotify.should_receive(:playlist).with("foo").and_return(@playlist)
|
187
|
+
@jotify.should_receive(:set_collaborative_flag).with(@playlist, true).and_return(true)
|
188
|
+
|
189
|
+
put '/playlists/foo', { 'collaborative' => true }.to_json
|
190
|
+
last_response.should be_ok
|
191
|
+
json_response.should == {'status'=>'OK', 'message'=>'update successful'}
|
192
|
+
end
|
193
|
+
|
194
|
+
|
174
195
|
it "should return 404 if playlist to update cannot be found" do
|
175
196
|
@jotify.should_receive(:playlist).with("foo").and_return(nil)
|
176
197
|
put '/playlists/foo', { 'tracks' => [ {'id'=>'1' }, { 'id'=>'2' } ] }.to_json
|
@@ -180,20 +201,20 @@ describe 'Api' do
|
|
180
201
|
|
181
202
|
it "should return 500 if playlist could not be updated" do
|
182
203
|
@jotify.should_receive(:playlist).with("foo").and_return(@playlist)
|
183
|
-
@jotify.should_receive(:
|
204
|
+
@jotify.should_receive(:set_tracks_on_playlist).with(@playlist, ['1','2']).and_return(false)
|
184
205
|
put '/playlists/foo', { 'tracks' => [ {'id'=>'1' }, { 'id'=>'2' } ] }.to_json
|
185
206
|
last_response.status.should == 500
|
186
|
-
json_response.should == {"status"=>"ERROR", "message"=>"could
|
207
|
+
json_response.should == {"status"=>"ERROR", "message"=>"could update tracks"}
|
187
208
|
end
|
188
209
|
|
189
|
-
it "should return 403 if invalid data is supplied" do
|
190
|
-
|
191
|
-
|
192
|
-
end
|
210
|
+
# it "should return 403 if invalid data is supplied" do
|
211
|
+
# @jotify.should_receive(:playlist).with("foo").and_return(@playlist)
|
212
|
+
# lambda { put '/playlists/foo', { 'foo' => 'bar' }.to_json }.should raise_error(ArgumentError)
|
213
|
+
# end
|
193
214
|
|
194
|
-
it "shouldn't do anything if no
|
215
|
+
it "shouldn't do anything if no data supplied" do
|
195
216
|
@jotify.should_receive(:playlist).with("foo").and_return(@playlist)
|
196
|
-
put '/playlists/foo', {
|
217
|
+
put '/playlists/foo', {}.to_json
|
197
218
|
last_response.should be_ok
|
198
219
|
end
|
199
220
|
end
|
data/spec/jotify_spec.rb
CHANGED
@@ -18,7 +18,7 @@ describe Jotify do
|
|
18
18
|
}.each { |id, expected| Jotify.resolve_id(id).should == expected }
|
19
19
|
end
|
20
20
|
|
21
|
-
it "should
|
21
|
+
it "should set tracks on playlist" do
|
22
22
|
@playlist = Jotify::Media::Playlist.new
|
23
23
|
@jotify_impl.should_receive(:playlistAddTracks) do |playlist, tracks, pos|
|
24
24
|
playlist.should be_a(Jotify::Media::Playlist)
|
@@ -27,6 +27,33 @@ describe Jotify do
|
|
27
27
|
tracks.should be_an(Java::JavaUtil::List)
|
28
28
|
tracks.size.should == 1
|
29
29
|
end
|
30
|
-
@jotify.
|
30
|
+
@jotify.set_tracks_on_playlist(@playlist, ['4d921ebcdd8c80f32ce1ed5acafbb9c8'])
|
31
31
|
end
|
32
|
+
|
33
|
+
it "should remove tracks before setting tracks on playlist" do
|
34
|
+
@playlist = Jotify::Media::Playlist.new
|
35
|
+
@playlist << empty_track
|
36
|
+
@jotify_impl.should_receive(:playlistRemoveTracks).and_return(true)
|
37
|
+
@jotify_impl.should_receive(:playlistAddTracks) do |playlist, tracks, pos|
|
38
|
+
playlist.should be_a(Jotify::Media::Playlist)
|
39
|
+
#playlist.should == @playlist
|
40
|
+
pos.should == 1
|
41
|
+
tracks.should be_an(Java::JavaUtil::List)
|
42
|
+
tracks.size.should == 1
|
43
|
+
end
|
44
|
+
@jotify.set_tracks_on_playlist(@playlist, ['4d921ebcdd8c80f32ce1ed5acafbb9c8'])
|
45
|
+
end
|
46
|
+
|
47
|
+
it "should rename the playlist" do
|
48
|
+
@playlist = Jotify::Media::Playlist.new
|
49
|
+
@jotify_impl.should_receive(:playlistRename).with(anything(), 'new').and_return(true)
|
50
|
+
@jotify.rename_playlist(@playlist, 'new').should == true
|
51
|
+
end
|
52
|
+
|
53
|
+
|
54
|
+
it "should rename the playlist" do
|
55
|
+
@playlist = Jotify::Media::Playlist.new
|
56
|
+
@jotify_impl.should_receive(:playlistSetCollaborative).with(anything(), true).and_return(true)
|
57
|
+
@jotify.set_collaborative_flag(@playlist, true).should == true
|
58
|
+
end
|
32
59
|
end
|
data/spotify-api.gemspec
CHANGED
@@ -2,11 +2,11 @@
|
|
2
2
|
|
3
3
|
Gem::Specification.new do |s|
|
4
4
|
s.name = %q{spotify-api}
|
5
|
-
s.version = "0.0.
|
5
|
+
s.version = "0.0.4"
|
6
6
|
|
7
7
|
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
8
8
|
s.authors = ["Jan Berkel"]
|
9
|
-
s.date = %q{2009-08-
|
9
|
+
s.date = %q{2009-08-08}
|
10
10
|
s.default_executable = %q{spotify-api-server}
|
11
11
|
s.description = %q{an api for spotify, based on jotify}
|
12
12
|
s.email = %q{jan.berkel@gmail.com}
|
@@ -25,6 +25,7 @@ Gem::Specification.new do |s|
|
|
25
25
|
"bin/spotify-api-server",
|
26
26
|
"examples/create_playlist.rb",
|
27
27
|
"examples/list_playlists.rb",
|
28
|
+
"examples/modify_playlist.rb",
|
28
29
|
"examples/search.rb",
|
29
30
|
"lib/jars/jotify.jar",
|
30
31
|
"lib/jotify.rb",
|
@@ -50,6 +51,7 @@ Gem::Specification.new do |s|
|
|
50
51
|
"spec/spec_helper.rb",
|
51
52
|
"examples/create_playlist.rb",
|
52
53
|
"examples/list_playlists.rb",
|
54
|
+
"examples/modify_playlist.rb",
|
53
55
|
"examples/search.rb"
|
54
56
|
]
|
55
57
|
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: jberkel-spotify-api
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.4
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Jan Berkel
|
@@ -9,7 +9,7 @@ autorequire:
|
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
11
|
|
12
|
-
date: 2009-08-
|
12
|
+
date: 2009-08-08 00:00:00 -07:00
|
13
13
|
default_executable: spotify-api-server
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
@@ -71,6 +71,7 @@ files:
|
|
71
71
|
- bin/spotify-api-server
|
72
72
|
- examples/create_playlist.rb
|
73
73
|
- examples/list_playlists.rb
|
74
|
+
- examples/modify_playlist.rb
|
74
75
|
- examples/search.rb
|
75
76
|
- lib/jars/jotify.jar
|
76
77
|
- lib/jotify.rb
|
@@ -117,4 +118,5 @@ test_files:
|
|
117
118
|
- spec/spec_helper.rb
|
118
119
|
- examples/create_playlist.rb
|
119
120
|
- examples/list_playlists.rb
|
121
|
+
- examples/modify_playlist.rb
|
120
122
|
- examples/search.rb
|