hallon 0.18.0 → 0.18.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (65) hide show
  1. data/.rspec +1 -1
  2. data/CHANGELOG.md +12 -1
  3. data/README.markdown +13 -5
  4. data/Rakefile +23 -74
  5. data/examples/example_support.rb +2 -0
  6. data/hallon.gemspec +1 -1
  7. data/lib/hallon.rb +1 -6
  8. data/lib/hallon/album.rb +4 -4
  9. data/lib/hallon/album_browse.rb +6 -6
  10. data/lib/hallon/artist.rb +3 -3
  11. data/lib/hallon/artist_browse.rb +9 -9
  12. data/lib/hallon/audio_queue.rb +2 -1
  13. data/lib/hallon/base.rb +10 -10
  14. data/lib/hallon/enumerator.rb +3 -3
  15. data/lib/hallon/ext/spotify.rb +1 -47
  16. data/lib/hallon/image.rb +4 -4
  17. data/lib/hallon/link.rb +4 -4
  18. data/lib/hallon/linkable.rb +10 -10
  19. data/lib/hallon/observable/playlist.rb +2 -3
  20. data/lib/hallon/observable/playlist_container.rb +3 -12
  21. data/lib/hallon/player.rb +2 -2
  22. data/lib/hallon/playlist.rb +6 -6
  23. data/lib/hallon/playlist_container.rb +8 -8
  24. data/lib/hallon/scrobbler.rb +4 -4
  25. data/lib/hallon/search.rb +20 -5
  26. data/lib/hallon/session.rb +18 -17
  27. data/lib/hallon/toplist.rb +4 -4
  28. data/lib/hallon/track.rb +5 -5
  29. data/lib/hallon/user.rb +7 -7
  30. data/lib/hallon/version.rb +1 -1
  31. data/spec/hallon/album_browse_spec.rb +1 -1
  32. data/spec/hallon/artist_browse_spec.rb +1 -1
  33. data/spec/hallon/base_spec.rb +6 -3
  34. data/spec/hallon/enumerator_spec.rb +2 -2
  35. data/spec/hallon/hallon_spec.rb +0 -4
  36. data/spec/hallon/link_spec.rb +1 -1
  37. data/spec/hallon/linkable_spec.rb +4 -4
  38. data/spec/hallon/observable/playlist_container_spec.rb +3 -3
  39. data/spec/hallon/observable/playlist_spec.rb +1 -1
  40. data/spec/hallon/player_spec.rb +9 -9
  41. data/spec/hallon/playlist_container_spec.rb +2 -2
  42. data/spec/hallon/playlist_spec.rb +8 -8
  43. data/spec/hallon/scrobbler_spec.rb +8 -7
  44. data/spec/hallon/search_spec.rb +3 -3
  45. data/spec/hallon/session_spec.rb +10 -10
  46. data/spec/hallon/toplist_spec.rb +4 -4
  47. data/spec/hallon/track_spec.rb +6 -6
  48. data/spec/hallon/user_post_spec.rb +1 -1
  49. data/spec/hallon/user_spec.rb +1 -1
  50. data/spec/mockspotify.rb +36 -42
  51. data/spec/mockspotify/mockspotify_spec.rb +15 -15
  52. data/spec/spec_helper.rb +25 -21
  53. data/spec/support/album_mocks.rb +4 -4
  54. data/spec/support/artist_mocks.rb +5 -5
  55. data/spec/support/image_mocks.rb +4 -4
  56. data/spec/support/playlist_container_mocks.rb +4 -4
  57. data/spec/support/playlist_mocks.rb +6 -6
  58. data/spec/support/search_mocks.rb +2 -2
  59. data/spec/support/session_mocks.rb +1 -1
  60. data/spec/support/shared_for_callbacks.rb +1 -1
  61. data/spec/support/shared_for_linkable_objects.rb +3 -2
  62. data/spec/support/toplist_mocks.rb +2 -2
  63. data/spec/support/track_mocks.rb +4 -4
  64. data/spec/support/user_mocks.rb +2 -2
  65. metadata +5 -5
@@ -82,8 +82,8 @@ module Hallon
82
82
  # @param [#to_s] appkey
83
83
  # @param [Hash] options
84
84
  # @option options [String] :user_agent ("Hallon") User-Agent to use (length < `256`)
85
- # @option options [String] :settings_path ("tmp") where to save settings and user-specific cache
86
- # @option options [String] :cache_path ("") where to save cache files (`""` to disable)
85
+ # @option options [String] :settings_location ("tmp") where to save settings and user-specific cache
86
+ # @option options [String] :cache_location ("") where to save cache files (`""` to disable)
87
87
  # @option options [String] :tracefile (nil) path to libspotify API tracefile (`nil` to disable)
88
88
  # @option options [String] :device_id (nil) device ID for offline synchronization (`nil` to disable)
89
89
  # @option options [String] :proxy (nil) proxy URI (supports http, https, socks4, socks5)
@@ -105,8 +105,8 @@ module Hallon
105
105
 
106
106
  @options = {
107
107
  :user_agent => "Hallon",
108
- :settings_path => "tmp/hallon/",
109
- :cache_path => "tmp/hallon/",
108
+ :settings_location => "tmp/hallon/",
109
+ :cache_location => "tmp/hallon/",
110
110
  :load_playlists => true,
111
111
  :compress_playlists => true,
112
112
  :cache_playlist_metadata => true,
@@ -125,18 +125,19 @@ module Hallon
125
125
  @cache_size = 0
126
126
 
127
127
  subscribe_for_callbacks do |callbacks|
128
- config = Spotify::SessionConfig.new
129
- config[:api_version] = Hallon::API_VERSION
130
- config.application_key = appkey
131
- @options.each { |(key, value)| config.send(:"#{key}=", value) }
132
- config[:callbacks] = callbacks
128
+ # not overridable
129
+ @options[:api_version] = Hallon::API_VERSION
130
+ @options[:initially_unload_playlists] = ! @options.delete(:load_playlists)
131
+ @options[:dont_save_metadata_for_playlists] = ! @options.delete(:cache_playlist_metadata)
132
+
133
+ config = Spotify::SessionConfig.new(@options.merge(application_key: appkey, callbacks: callbacks))
133
134
 
134
135
  instance_eval(&block) if block_given?
135
136
 
136
137
  # You pass a pointer to the session pointer to libspotify >:)
137
138
  FFI::MemoryPointer.new(:pointer) do |p|
138
139
  Error::maybe_raise Spotify.session_create(config, p)
139
- @pointer = p.read_pointer
140
+ @pointer = Spotify::Session.new(p.read_pointer)
140
141
  end
141
142
  end
142
143
  end
@@ -155,7 +156,7 @@ module Hallon
155
156
  # @note returns nil if the session is not logged in.
156
157
  # @return [PlaylistContainer, nil]
157
158
  def container
158
- container = Spotify.session_playlistcontainer!(pointer)
159
+ container = Spotify.session_playlistcontainer(pointer)
159
160
  PlaylistContainer.from(container)
160
161
  end
161
162
 
@@ -198,7 +199,7 @@ module Hallon
198
199
  # @raise [Spotify::Error] if no credentials are stored in libspotify
199
200
  # @see #relogin!
200
201
  def relogin
201
- Spotify.session_relogin!(pointer)
202
+ Spotify.try(:session_relogin, pointer)
202
203
  end
203
204
 
204
205
  # Log in to Spotify using the given credentials.
@@ -267,7 +268,7 @@ module Hallon
267
268
 
268
269
  # @return [User] the User currently logged in.
269
270
  def user
270
- user = Spotify.session_user!(pointer)
271
+ user = Spotify.session_user(pointer)
271
272
  User.from(user)
272
273
  end
273
274
 
@@ -411,20 +412,20 @@ module Hallon
411
412
  # @see Player.bitrates
412
413
  def offline_bitrate=(bitrate)
413
414
  bitrate, resync = Array(bitrate)
414
- Spotify.session_preferred_offline_bitrate!(pointer, bitrate, !! resync)
415
+ Spotify.try(:session_preferred_offline_bitrate, pointer, bitrate, !! resync)
415
416
  end
416
417
 
417
418
  # @note Returns nil when no user is logged in.
418
419
  # @return [Playlist, nil] currently logged in user’s starred playlist.
419
420
  def starred
420
- playlist = Spotify.session_starred_create!(pointer)
421
+ playlist = Spotify.session_starred_create(pointer)
421
422
  Playlist.from(playlist)
422
423
  end
423
424
 
424
425
  # @note Returns nil when no user is logged in.
425
426
  # @return [Playlist, nil] currently logged in user’s inbox playlist.
426
427
  def inbox
427
- playlist = Spotify.session_inbox_create!(pointer)
428
+ playlist = Spotify.session_inbox_create(pointer)
428
429
  Playlist.from(playlist)
429
430
  end
430
431
 
@@ -461,7 +462,7 @@ module Hallon
461
462
  def tracks_starred(tracks, starred)
462
463
  FFI::MemoryPointer.new(:pointer, tracks.size) do |ptr|
463
464
  ptr.write_array_of_pointer tracks.map(&:pointer)
464
- Spotify.track_set_starred!(pointer, ptr, tracks.size, starred)
465
+ Spotify.try(:track_set_starred, pointer, ptr, tracks.size, starred)
465
466
  end
466
467
  end
467
468
 
@@ -11,7 +11,7 @@ module Hallon
11
11
  size :toplistbrowse_num_tracks
12
12
 
13
13
  # @return [Track, nil]
14
- item :toplistbrowse_track! do |track|
14
+ item :toplistbrowse_track do |track|
15
15
  Track.from(track)
16
16
  end
17
17
  end
@@ -21,7 +21,7 @@ module Hallon
21
21
  size :toplistbrowse_num_albums
22
22
 
23
23
  # @return [Album, nil]
24
- item :toplistbrowse_album! do |album|
24
+ item :toplistbrowse_album do |album|
25
25
  Album.from(album)
26
26
  end
27
27
  end
@@ -31,7 +31,7 @@ module Hallon
31
31
  size :toplistbrowse_num_artists
32
32
 
33
33
  # @return [Artist, nil]
34
- item :toplistbrowse_artist! do |artist|
34
+ item :toplistbrowse_artist do |artist|
35
35
  Artist.from(artist)
36
36
  end
37
37
  end
@@ -72,7 +72,7 @@ module Hallon
72
72
 
73
73
  subscribe_for_callbacks do |callback|
74
74
  @type = type
75
- @pointer = Spotify.toplistbrowse_create!(session.pointer, type, region, user, callback, nil)
75
+ @pointer = Spotify.toplistbrowse_create(session.pointer, type, region, user, callback, nil)
76
76
  end
77
77
  end
78
78
 
@@ -10,7 +10,7 @@ module Hallon
10
10
  size :track_num_artists
11
11
 
12
12
  # @return [Artist, nil]
13
- item :track_artist! do |artist|
13
+ item :track_artist do |artist|
14
14
  Artist.from(artist)
15
15
  end
16
16
  end
@@ -43,7 +43,7 @@ module Hallon
43
43
  # @param [String, Link, FFI::Pointer] link
44
44
  def initialize(link)
45
45
  FFI::MemoryPointer.new(:int) do |ptr|
46
- @pointer = to_pointer(link, :track, ptr)
46
+ @pointer = to_pointer(link, Spotify::Track, ptr)
47
47
  @offset = Rational(ptr.read_int, 1000)
48
48
  end
49
49
  end
@@ -74,7 +74,7 @@ module Hallon
74
74
  # @param [Integer] length
75
75
  # @return [Track]
76
76
  def self.local(title, artist, album = nil, length = nil)
77
- track = Spotify.localtrack_create!(artist, title, album || "", length || -1)
77
+ track = Spotify.localtrack_create(artist, title, album || "", length || -1)
78
78
  new(track)
79
79
  end
80
80
 
@@ -157,7 +157,7 @@ module Hallon
157
157
 
158
158
  # @return [Hallon::Album] album this track belongs to.
159
159
  def album
160
- album = Spotify.track_album!(pointer)
160
+ album = Spotify.track_album(pointer)
161
161
  Album.from(album)
162
162
  end
163
163
 
@@ -188,7 +188,7 @@ module Hallon
188
188
  # @see autolinked?
189
189
  # @return [Track] the track this track is autolinked to for audio playback.
190
190
  def playable_track
191
- track = Spotify.track_get_playable!(session.pointer, pointer)
191
+ track = Spotify.track_get_playable(session.pointer, pointer)
192
192
  Track.from(track)
193
193
  end
194
194
 
@@ -47,7 +47,7 @@ module Hallon
47
47
  @tracks = tracks
48
48
  @message = message
49
49
  @recipient_name = recipient_name
50
- @pointer = Spotify.inbox_post_tracks!(session.pointer, @recipient_name, ary, tracks.length, @message, callback, nil)
50
+ @pointer = Spotify.inbox_post_tracks(session.pointer, @recipient_name, ary, tracks.length, @message, callback, nil)
51
51
  end
52
52
  end
53
53
 
@@ -72,7 +72,7 @@ module Hallon
72
72
  include Loadable
73
73
 
74
74
  from_link :profile do |link|
75
- Spotify.link_as_user!(link)
75
+ Spotify.link_as_user(link)
76
76
  end
77
77
 
78
78
  to_link :from_user
@@ -86,11 +86,11 @@ module Hallon
86
86
  # Hallon::User.new("spotify:user:burgestrand")
87
87
  #
88
88
  # @note You can also instantiate User with a canonical username
89
- # @param [String, Link, Spotify::Pointer] link
89
+ # @param [String, Link, Spotify::User] link
90
90
  def initialize(link)
91
- @pointer = to_pointer(link, :user) do
91
+ @pointer = to_pointer(link, Spotify::User) do
92
92
  if link.is_a?(String) and link !~ /\Aspotify:user:/
93
- to_pointer("spotify:user:#{link}", :user)
93
+ to_pointer("spotify:user:#{link}", Spotify::User)
94
94
  end
95
95
  end
96
96
  end
@@ -114,14 +114,14 @@ module Hallon
114
114
  # @note Returns nil unless {User#loaded?}
115
115
  # @return [Playlist, nil] starred playlist of the User.
116
116
  def starred
117
- playlist = Spotify.session_starred_for_user_create!(session.pointer, name)
117
+ playlist = Spotify.session_starred_for_user_create(session.pointer, name)
118
118
  Playlist.from(playlist)
119
119
  end
120
120
 
121
121
  # @note Returns nil unless {#loaded?}
122
122
  # @return [PlaylistContainer, nil] published playlists of the User.
123
123
  def published
124
- container = Spotify.session_publishedcontainer_for_user_create!(session.pointer, name)
124
+ container = Spotify.session_publishedcontainer_for_user_create(session.pointer, name)
125
125
  PlaylistContainer.from(container)
126
126
  end
127
127
 
@@ -3,5 +3,5 @@ module Hallon
3
3
  # Current release version of Hallon
4
4
  #
5
5
  # @see http://semver.org/
6
- VERSION = [0, 18, 0].join('.')
6
+ VERSION = [0, 18, 1].join('.')
7
7
  end
@@ -14,7 +14,7 @@ describe Hallon::AlbumBrowse do
14
14
 
15
15
  describe ".new" do
16
16
  it "should raise an error if the browse request failed" do
17
- Spotify.should_receive(:albumbrowse_create).and_return(null_pointer)
17
+ spotify_api.should_receive(:albumbrowse_create).and_return(null_pointer)
18
18
  expect { Hallon::AlbumBrowse.new(mock_album) }.to raise_error(FFI::NullPointerError)
19
19
  end
20
20
 
@@ -15,7 +15,7 @@ describe Hallon::ArtistBrowse do
15
15
 
16
16
  describe ".new" do
17
17
  it "should raise an error if the browse request failed" do
18
- Spotify.should_receive(:artistbrowse_create).and_return(null_pointer)
18
+ spotify_api.should_receive(:artistbrowse_create).and_return(null_pointer)
19
19
  expect { Hallon::ArtistBrowse.new(mock_artist) }.to raise_error(FFI::NullPointerError)
20
20
  end
21
21
 
@@ -1,15 +1,18 @@
1
+ class Spotify::BasePointer < Spotify::ManagedPointer
2
+ end
3
+
1
4
  describe Hallon::Base do
2
5
  let(:klass) do
3
6
  Class.new(Hallon::Base) do
4
7
  def initialize(pointer)
5
- @pointer = to_pointer(pointer, :base) { |x| x }
8
+ @pointer = to_pointer(pointer, Spotify::BasePointer) { |x| x }
6
9
  end
7
10
  end
8
11
  end
9
12
 
10
13
  let(:base_pointer) do
11
- Spotify.stub(:base_add_ref! => nil, :base_release! => nil)
12
- Spotify::Pointer.new(a_pointer, :base, true)
14
+ spotify_api.stub(:base_pointer_release => nil)
15
+ Spotify::BasePointer.new(a_pointer)
13
16
  end
14
17
 
15
18
  describe "#to_pointer" do
@@ -1,8 +1,8 @@
1
1
  # coding: utf-8
2
2
  describe Hallon::Enumerator do
3
3
  def enumerator(items)
4
- Spotify.stub(:enumerator_size => items)
5
- Spotify.stub(:enumerator_item).and_return { |_, i| alphabet[i] }
4
+ spotify_api.stub(:enumerator_size => items)
5
+ spotify_api.stub(:enumerator_item).and_return { |_, i| alphabet[i] }
6
6
 
7
7
  klass = Class.new(Hallon::Enumerator) do
8
8
  size :enumerator_size
@@ -8,10 +8,6 @@ describe Hallon do
8
8
  specify { Hallon::API_VERSION.should == 12 }
9
9
  end
10
10
 
11
- describe "API_BUILD" do
12
- specify { Hallon::API_BUILD.should be_a String }
13
- end
14
-
15
11
  describe "URI" do
16
12
  example_uris.keys.each do |uri|
17
13
  specify(uri) { Hallon::URI.match(uri)[0].should eq uri }
@@ -13,7 +13,7 @@ describe Hallon::Link do
13
13
  end
14
14
 
15
15
  it "should raise an error given a null pointer" do
16
- expect { Hallon::Link.new(Spotify::Pointer.new(null_pointer, :link, false)) }.to raise_error(ArgumentError)
16
+ expect { Hallon::Link.new(Spotify::Link.new(null_pointer)) }.to raise_error(ArgumentError)
17
17
  end
18
18
 
19
19
  it "should raise an error when no session instance is about" do
@@ -10,7 +10,7 @@ describe Hallon::Linkable do
10
10
  let(:object) { klass.new }
11
11
  let(:pointer) { FFI::Pointer.new(1) }
12
12
 
13
- before(:each) { Spotify.stub(:link_as_search!) }
13
+ before(:each) { spotify_api.stub(:link_as_search) }
14
14
 
15
15
  it "should define the #from_link method" do
16
16
  object.respond_to?(:from_link, true).should be_false
@@ -24,7 +24,7 @@ describe Hallon::Linkable do
24
24
 
25
25
  describe "#to_link" do
26
26
  it "should return nil if link creation failed" do
27
- Spotify.should_receive(:link_create_from_user).and_return(null_pointer)
27
+ spotify_api.should_receive(:link_create_from_user).and_return(null_pointer)
28
28
 
29
29
  klass.instance_eval do
30
30
  to_link(:from_user)
@@ -48,7 +48,7 @@ describe Hallon::Linkable do
48
48
 
49
49
  describe "#from_link" do
50
50
  it "should call the appropriate Spotify function" do
51
- Spotify.should_receive(:link_as_search!).and_return(pointer)
51
+ spotify_api.should_receive(:link_as_search).and_return(pointer)
52
52
 
53
53
  klass.instance_eval do
54
54
  from_link(:as_search)
@@ -58,7 +58,7 @@ describe Hallon::Linkable do
58
58
  end
59
59
 
60
60
  it "should call the given block if necessary" do
61
- Spotify.should_not_receive(:link_as_search!)
61
+ spotify_api.should_not_receive(:link_as_search)
62
62
 
63
63
  called = false
64
64
  pointer = double(:null? => false)
@@ -1,16 +1,16 @@
1
1
  describe Hallon::Observable::PlaylistContainer do
2
2
  specification_for_callback "playlist_added" do
3
- let(:input) { [a_pointer, mock_playlist_raw, 3, :userdata] }
3
+ let(:input) { [a_pointer, mock_playlist, 3, :userdata] }
4
4
  let(:output) { [Hallon::Playlist.new(mock_playlist), 3] }
5
5
  end
6
6
 
7
7
  specification_for_callback "playlist_removed" do
8
- let(:input) { [a_pointer, mock_playlist_raw, 3, :userdata] }
8
+ let(:input) { [a_pointer, mock_playlist, 3, :userdata] }
9
9
  let(:output) { [Hallon::Playlist.new(mock_playlist), 3] }
10
10
  end
11
11
 
12
12
  specification_for_callback "playlist_moved" do
13
- let(:input) { [a_pointer, mock_playlist_raw, 3, 8, :userdata] }
13
+ let(:input) { [a_pointer, mock_playlist, 3, 8, :userdata] }
14
14
  let(:output) { [Hallon::Playlist.new(mock_playlist), 3, 8] }
15
15
  end
16
16
 
@@ -52,7 +52,7 @@ describe Hallon::Observable::Playlist do
52
52
  end
53
53
 
54
54
  specification_for_callback "track_created_changed" do
55
- let(:input) { [a_pointer, 7, mock_user_raw, 15, :userdata] }
55
+ let(:input) { [a_pointer, 7, mock_user, 15, :userdata] }
56
56
  let(:output) { [7, Hallon::User.new(mock_user), Time.at(15)] }
57
57
  end
58
58
 
@@ -31,43 +31,43 @@ describe Hallon::Player do
31
31
 
32
32
  describe "#load" do
33
33
  it "should load the given track" do
34
- Spotify.should_receive(:session_player_load).with(session.pointer, track.pointer)
34
+ spotify_api.should_receive(:session_player_load).with(session.pointer, track.pointer)
35
35
  player.load(track)
36
36
  end
37
37
 
38
38
  it "should try to instantiate the track if it’s not a track" do
39
- Spotify.should_receive(:session_player_load).with(session.pointer, track.pointer)
39
+ spotify_api.should_receive(:session_player_load).with(session.pointer, track.pointer)
40
40
  player.load(track.to_str)
41
41
  end
42
42
 
43
43
  it "should raise an error if load was unsuccessful" do
44
- Spotify.should_receive(:session_player_load).and_return(:is_loading)
44
+ spotify_api.should_receive(:session_player_load).and_return(:is_loading)
45
45
  expect { player.load(track) }.to raise_error(Hallon::Error, /IS_LOADING/)
46
46
  end
47
47
  end
48
48
 
49
49
  describe "#stop" do
50
50
  it "should unload the currently loaded track" do
51
- Spotify.should_receive(:session_player_unload).with(session.pointer)
51
+ spotify_api.should_receive(:session_player_unload).with(session.pointer)
52
52
  player.stop
53
53
  end
54
54
  end
55
55
 
56
56
  describe "#prefetch" do
57
57
  it "should set up given track for prefetching" do
58
- Spotify.should_receive(:session_player_prefetch).with(session.pointer, track.pointer)
58
+ spotify_api.should_receive(:session_player_prefetch).with(session.pointer, track.pointer)
59
59
  player.prefetch(track)
60
60
  end
61
61
  end
62
62
 
63
63
  describe "#play" do
64
64
  it "should start playback of given track" do
65
- Spotify.should_receive(:session_player_play).with(session.pointer, true)
65
+ spotify_api.should_receive(:session_player_play).with(session.pointer, true)
66
66
  player.play
67
67
  end
68
68
 
69
69
  it "should load and play given track if one was given" do
70
- Spotify.should_receive(:session_player_play).with(session.pointer, true)
70
+ spotify_api.should_receive(:session_player_play).with(session.pointer, true)
71
71
  player.should_receive(:load).with(track)
72
72
  player.play(track)
73
73
  end
@@ -75,14 +75,14 @@ describe Hallon::Player do
75
75
 
76
76
  describe "#pause" do
77
77
  it "should stop playback of given track" do
78
- Spotify.should_receive(:session_player_play).with(session.pointer, false)
78
+ spotify_api.should_receive(:session_player_play).with(session.pointer, false)
79
79
  player.pause
80
80
  end
81
81
  end
82
82
 
83
83
  describe "#seek" do
84
84
  it "should set up the currently loaded track at given position" do
85
- Spotify.should_receive(:session_player_seek).with(session.pointer, 1000)
85
+ spotify_api.should_receive(:session_player_seek).with(session.pointer, 1000)
86
86
  player.seek(1)
87
87
  end
88
88
  end