jberkel-spotify-api 0.0.3 → 0.0.4

Sign up to get free protection for your applications and to get access to all the features.
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
- * add tracks to playlist [PUT /playlists/id]
17
+ * update playlists [PUT /playlists/id]
18
18
 
19
19
  ## Installation
20
20
 
@@ -1,4 +1,4 @@
1
1
  ---
2
- :patch: 3
2
+ :patch: 4
3
3
  :major: 0
4
4
  :minor: 0
@@ -1,5 +1,5 @@
1
- #!/usr/bin/env jruby
2
- $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
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
@@ -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
@@ -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 add_tracks_to_playlist(playlist, track_ids)
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
- @jotify.playlistAddTracks(playlist, tracks, 0)
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)
@@ -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 { |p| p.to_h } }
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.add_tracks_to_playlist(playlist, ids)
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
- if jotify.add_tracks_to_playlist(playlist, ids)
112
- return 200, { 'status' => 'OK', 'message' => "successfully added #{ids.size} tracks" }.to_json
113
- else
114
- return 500, { 'status' => 'ERROR', 'message' => 'could not add to playlist' }.to_json
115
- end
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
 
@@ -27,6 +27,10 @@ module Java
27
27
  tracks.size
28
28
  end
29
29
 
30
+ def collaborative?
31
+ isCollaborative()
32
+ end
33
+
30
34
  def inspect
31
35
  "[Playlist: #{self.getId()} #{getTracks.to_a}]"
32
36
  end
@@ -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
- "tracks"=>[], "author"=>"test", "revision"=>-1, "collaborative"=>false
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/update" do
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(:add_tracks_to_playlist).with(@playlist, ['1','2']).and_return(true)
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(:add_tracks_to_playlist).with(@playlist, ['1','2']).and_return(true)
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'=>'successfully added 2 tracks'}
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(:add_tracks_to_playlist).with(@playlist, ['1','2']).and_return(false)
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 not add to playlist"}
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
- @jotify.should_receive(:playlist).with("foo").and_return(@playlist)
191
- lambda { put '/playlists/foo', { 'foo' => 'bar' }.to_json }.should raise_error(ArgumentError)
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 track ids supplied" do
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', { 'tracks' => [] }.to_json
217
+ put '/playlists/foo', {}.to_json
197
218
  last_response.should be_ok
198
219
  end
199
220
  end
@@ -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 add tracks to playlist" do
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.add_tracks_to_playlist(@playlist, ['4d921ebcdd8c80f32ce1ed5acafbb9c8'])
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
@@ -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.3"
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-07}
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.3
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-07 00:00:00 -07:00
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