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 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