spotify 12.5.2 → 12.5.3

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 981b598f43ddd1bb8c920bc52227349cc3c38983
4
- data.tar.gz: fcc1deabbf3d31c131c870edd7a08366f0267134
3
+ metadata.gz: 4d9e97a03f155c02b4b189899d152e51acc80c21
4
+ data.tar.gz: 43731fc0330043a6885b08c669c2fb13418efb68
5
5
  SHA512:
6
- metadata.gz: 8d7b1a66718c08753571a3cbd0d720fd9c34bd7692baeecf9304731ff7b0181dfda43d6c4cc050635672e8beebe9e89780cc3d86addc28b01615fb236d3a381c
7
- data.tar.gz: 7876ab5a93a7316f087a949a8c32e26218a4b969d4cb0641374c610ab2cae9caa2f64fa32950a649befccf4d8794ce7ce38237c97b9f0ca3988ac31c8c0ea091
6
+ metadata.gz: 519bd5a79bb4a76dd63cb2ad884cb42da3a7bc142cf851db490bdc6f35f21be15fc224911f80650a437e7152db3cd0ad4901ce25e0d62f414aea8aec900447cf
7
+ data.tar.gz: f0b4bc4da8b176121aa4cb62c276142086084e8d8334fc291d76a740693ec218f170c6cf478023d0a971b04a27c68fab07b80f7a14c1c6625f66fbe00f1c5fbb
@@ -1,6 +1,14 @@
1
1
  [HEAD][]
2
2
  -----------
3
3
 
4
+ [v12.5.3][]
5
+ -----------
6
+
7
+ - [e09f64cc7] Add initial windows support
8
+
9
+ I’ve noticed callbacks cause libspotify to segfault. Not sure why; could
10
+ have something to do with with FFI callback support.
11
+
4
12
  [v12.5.2][]
5
13
  -----------
6
14
 
@@ -198,8 +206,9 @@ v0.0.0
198
206
  ------
199
207
  - release to register rubygems.org name
200
208
 
201
- [HEAD]: https://github.com/Burgestrand/spotify/compare/v12.5.2...HEAD
209
+ [HEAD]: https://github.com/Burgestrand/spotify/compare/v12.5.3...HEAD
202
210
 
211
+ [v12.5.2]: https://github.com/Burgestrand/spotify/compare/v12.5.2...v12.5.3
203
212
  [v12.5.2]: https://github.com/Burgestrand/spotify/compare/v12.5.1...v12.5.2
204
213
  [v12.5.1]: https://github.com/Burgestrand/spotify/compare/v12.5.0...v12.5.1
205
214
  [v12.5.0]: https://github.com/Burgestrand/spotify/compare/v12.4.0...v12.5.0
data/Gemfile CHANGED
@@ -1,4 +1,5 @@
1
- source :rubygems
1
+ source 'https://rubygems.org/'
2
+
2
3
  gemspec
3
4
 
4
5
  gem 'pry'
@@ -1,5 +1,9 @@
1
- Ruby bindings for [libspotify][] ([![Build Status](https://secure.travis-ci.org/Burgestrand/spotify.png?branch=master)](http://travis-ci.org/Burgestrand/spotify))
2
- ================================
1
+ Low-level Ruby bindings for [libspotify][], the official Spotify C API
2
+ ======================================================================
3
+ [![Build Status](https://secure.travis-ci.org/Burgestrand/spotify.png?branch=master)](http://travis-ci.org/Burgestrand/spotify)
4
+ [![Dependency Status](https://gemnasium.com/Burgestrand/spotify.png)](https://gemnasium.com/Burgestrand/spotify)
5
+ [![Code Climate](https://codeclimate.com/github/Burgestrand/spotify.png)](https://codeclimate.com/github/Burgestrand/spotify)
6
+ [![Gem Version](https://badge.fury.io/rb/spotify.png)](http://badge.fury.io/rb/spotify)
3
7
 
4
8
  The libspotify C API package allows third party developers to write
5
9
  applications that utilize the Spotify music streaming service.
@@ -16,7 +20,7 @@ The Spotify gem has:
16
20
 
17
21
  - [100% API coverage][], including callback support. You’ll be able to use any function from the libspotify library.
18
22
  - [Automatic garbage collection][]. Piggybacking on Ruby’s GC to manage pointer lifecycle.
19
- - [Parallell function call protection][]. libspotify is not thread-safe, but Spotify protects you.
23
+ - [Parallell function call protection][]. libspotify is not thread-safe, but Spotify protects you by providing a re-entrant mutex around function calls.
20
24
  - [Type conversion and type safety][]. Special pointers for every Spotify type, protecting you from accidental mix-ups.
21
25
  - [Support for JRuby and Rubinius][]. Thanks to FFI, the gem runs fine on the main three Ruby implementations!
22
26
 
@@ -26,7 +30,14 @@ The Spotify gem has:
26
30
  [Type conversion and type safety]: http://rdoc.info/github/Burgestrand/spotify/master/Spotify/ManagedPointer
27
31
  [Support for JRuby and Rubinius]: https://github.com/Burgestrand/spotify/blob/master/.travis.yml
28
32
 
29
- The Spotify gem is aimed at experienced developers
33
+ Contact details
34
+ ---------------
35
+
36
+ - __Got questions?__ Ask on the mailing list: [ruby-hallon@googlegroups.com][] (<https://groups.google.com/d/forum/ruby-hallon>)
37
+ - __Found a bug?__ Report an issue: <https://github.com/Burgestrand/spotify/issues/new>
38
+ - __Have feedback?__ I ❤ feedback! Please send it to the mailing list.
39
+
40
+ Spotify API is best used with a supporting library
30
41
  --------------------------------------------------
31
42
  As the raw libspotify API is exposed, the Spotify gem is best coupled with a supporting
32
43
  library. This library would take a more focused approach to which kind of applications
@@ -88,6 +99,6 @@ THE SOFTWARE.
88
99
 
89
100
  [semantic versioning (semver.org)]: http://semver.org/
90
101
  [ruby-hallon@googlegroups.com]: mailto:ruby-hallon@googlegroups.com
91
- [libspotify]: http://developer.spotify.com/en/libspotify/overview/
102
+ [libspotify]: https://developer.spotify.com/technologies/libspotify/
92
103
  [Spotify]: https://www.spotify.com/
93
104
  [Hallon]: https://github.com/Burgestrand/Hallon
@@ -9,7 +9,7 @@ require "plaything"
9
9
  def play_track(uri)
10
10
  link = Spotify.link_create_from_string(uri)
11
11
  track = Spotify.link_as_track(link)
12
- poll($session) { Spotify.track_is_loaded(track) }
12
+ Support.poll($session) { Spotify.track_is_loaded(track) }
13
13
  Spotify.try(:session_player_play, $session, false)
14
14
  Spotify.try(:session_player_load, $session, track)
15
15
  Spotify.try(:session_player_play, $session, true)
@@ -84,12 +84,12 @@ $session_callbacks = {
84
84
 
85
85
  music_delivery: proc do |session, format, frames, num_frames|
86
86
  if num_frames == 0
87
- plaything.stop
88
87
  $logger.debug("session (player)") { "music delivery audio discontuity" }
88
+ plaything.stop
89
+ 0
89
90
  else
90
91
  frames = FrameReader.new(format[:channels], format[:sample_type], num_frames, frames)
91
92
  consumed_frames = plaything.stream(frames, format.to_h)
92
- $logger.info("session (player)") { "#{format.to_h}" }
93
93
  $logger.debug("session (player)") { "music delivery #{consumed_frames} of #{num_frames}" }
94
94
  consumed_frames
95
95
  end
@@ -120,21 +120,17 @@ config = Spotify::SessionConfig.new({
120
120
  })
121
121
 
122
122
  $logger.info "Creating session."
123
- FFI::MemoryPointer.new(Spotify::Session) do |ptr|
124
- Spotify.try(:session_create, config, ptr)
125
- $session = Spotify::Session.new(ptr.read_pointer)
126
- end
123
+ $session = Support.create_session(config)
127
124
 
128
125
  $logger.info "Created! Logging in."
129
- Spotify.session_login($session, $username, $password, false, nil)
126
+ Spotify.session_login($session, $username, $password, false, $blob)
130
127
 
131
128
  $logger.info "Log in requested. Waiting forever until logged in."
132
- poll($session) { Spotify.session_connectionstate($session) == :logged_in }
129
+ Support.poll($session) { Spotify.session_connectionstate($session) == :logged_in }
133
130
 
134
131
  $logger.info "Logged in as #{Spotify.session_user_name($session)}."
135
132
 
136
- print "Spotify track URI: "
137
- play_track gets.chomp
133
+ play_track Support.prompt("Spotify track URI")
138
134
 
139
135
  $logger.info "Playing track until end. Use ^C to exit."
140
- poll($session) { $end_of_track }
136
+ Support.poll($session) { $end_of_track }
@@ -13,10 +13,7 @@ config = Spotify::SessionConfig.new({
13
13
  })
14
14
 
15
15
  $logger.info "Creating session."
16
- FFI::MemoryPointer.new(Spotify::Session) do |ptr|
17
- Spotify.try(:session_create, config, ptr)
18
- $session = Spotify::Session.new(ptr.read_pointer)
19
- end
16
+ $session = Support.create_session(config)
20
17
 
21
18
  $logger.info "Created! Logging in."
22
19
  Spotify.session_login($session, $username, $password, false, nil)
@@ -7,6 +7,7 @@ require "pry"
7
7
  Thread.abort_on_exception = true
8
8
 
9
9
  # We use a logger to print some information on when things are happening.
10
+ $stderr.sync = true
10
11
  $logger = Logger.new($stderr)
11
12
  $logger.level = Logger::INFO
12
13
 
@@ -14,33 +15,52 @@ $logger.level = Logger::INFO
14
15
  # Some utility.
15
16
  #
16
17
 
17
- # libspotify supports callbacks, but they are not useful for waiting on
18
- # operations (how they fire can be strange at times, and sometimes they
19
- # might not fire at all). As a result, polling is the way to go.
20
- def poll(session)
21
- until yield
22
- FFI::MemoryPointer.new(:int) do |ptr|
23
- Spotify.session_process_events(session, ptr)
18
+ module Support
19
+ module_function
20
+
21
+ def logger
22
+ $logger
23
+ end
24
+
25
+ # libspotify supports callbacks, but they are not useful for waiting on
26
+ # operations (how they fire can be strange at times, and sometimes they
27
+ # might not fire at all). As a result, polling is the way to go.
28
+ def poll(session)
29
+ until yield
30
+ FFI::MemoryPointer.new(:int) do |ptr|
31
+ Spotify.session_process_events(session, ptr)
32
+ end
33
+ sleep(0.1)
24
34
  end
25
- sleep(0.1)
26
35
  end
27
- end
28
36
 
29
- # For making sure fetching configuration options fail with a useful error
30
- # message when running the examples.
31
- def env(name)
32
- ENV.fetch(name) do
33
- raise "Missing ENV['#{name}']. Please: export #{name}='your value'"
37
+ # For making sure fetching configuration options fail with a useful error
38
+ # message when running the examples.
39
+ def env(name)
40
+ ENV.fetch(name) do
41
+ raise "Missing ENV['#{name}']. Please: export #{name}='your value'"
42
+ end
34
43
  end
35
- end
36
44
 
37
- # Ask the user for input with a prompt explaining what kind of input.
38
- def prompt(message)
39
- print "#{message}: "
40
- gets.chomp
45
+ # Ask the user for input with a prompt explaining what kind of input.
46
+ def prompt(message)
47
+ print "#{message}: "
48
+ gets.chomp
49
+ end
50
+
51
+ def create_session(config)
52
+ FFI::MemoryPointer.new(Spotify::Session) do |ptr|
53
+ Spotify.try(:session_create, config, ptr)
54
+ return Spotify::Session.new(ptr.read_pointer)
55
+ end
56
+ end
41
57
  end
42
58
 
43
59
  # Load the configuration.
44
60
  $appkey = IO.read("./spotify_appkey.key", encoding: "BINARY")
45
- $username = env("SPOTIFY_USERNAME")
46
- $password = env("SPOTIFY_PASSWORD")
61
+ $username = Support.env("SPOTIFY_USERNAME")
62
+ if ENV.has_key?("SPOTIFY_BLOB")
63
+ $blob = ENV["SPOTIFY_BLOB"]
64
+ else
65
+ $password = Support.env("SPOTIFY_PASSWORD")
66
+ end
@@ -13,20 +13,17 @@ config = Spotify::SessionConfig.new({
13
13
  })
14
14
 
15
15
  $logger.info "Creating session."
16
- FFI::MemoryPointer.new(Spotify::Session) do |ptr|
17
- Spotify.try(:session_create, config, ptr)
18
- $session = Spotify::Session.new(ptr.read_pointer)
19
- end
16
+ $session = Support.create_session(config)
20
17
 
21
18
  $logger.info "Created! Logging in."
22
- Spotify.session_login($session, $username, $password, false, nil)
19
+ Spotify.session_login($session, $username, $password, false, $blob)
23
20
 
24
21
  $logger.info "Log in requested. Waiting forever until logged in."
25
- poll($session) { Spotify.session_connectionstate($session) == :logged_in }
22
+ Support.poll($session) { Spotify.session_connectionstate($session) == :logged_in }
26
23
 
27
24
  $logger.info "Logged in as #{Spotify.session_user_name($session)}."
28
25
 
29
- track_uri = prompt("Please enter an track URI")
26
+ track_uri = Support.prompt("Please enter an track URI")
30
27
  link = Spotify.link_create_from_string(track_uri)
31
28
 
32
29
  if link.null?
@@ -40,7 +37,7 @@ else
40
37
  end
41
38
 
42
39
  $logger.info "Attempting to load track. Waiting forever until successful."
43
- poll($session) { Spotify.track_is_loaded(track) }
40
+ Support.poll($session) { Spotify.track_is_loaded(track) }
44
41
  $logger.info "Track loaded."
45
42
 
46
43
  puts Spotify.track_name(track)
@@ -24,6 +24,10 @@ $session_callbacks = {
24
24
  logged_out: lambda do |session|
25
25
  $logger.info('session (logged out)') { 'logged out!' }
26
26
  end,
27
+
28
+ credentials_blob_updated: lambda do |session, blob|
29
+ $logger.info('session (blob)') { blob }
30
+ end
27
31
  }
28
32
 
29
33
  #
@@ -43,17 +47,12 @@ config = Spotify::SessionConfig.new({
43
47
  })
44
48
 
45
49
  $logger.info "Creating session."
46
- FFI::MemoryPointer.new(Spotify::Session) do |ptr|
47
- # Spotify.try is a special method. It raises a ruby exception if the returned spotify
48
- # error code is an error.
49
- Spotify.try(:session_create, config, ptr)
50
- $session = Spotify::Session.new(ptr.read_pointer)
51
- end
50
+ $session = Support.create_session(config)
52
51
 
53
52
  $logger.info "Created! Logging in."
54
- Spotify.session_login($session, $username, $password, false, nil)
53
+ Spotify.session_login($session, $username, $password, false, $blob)
55
54
 
56
55
  $logger.info "Log in requested. Waiting forever until logged in."
57
- poll($session) { Spotify.session_connectionstate($session) == :logged_in }
56
+ Support.poll($session) { Spotify.session_connectionstate($session) == :logged_in }
58
57
 
59
58
  $logger.info "Logged in as #{Spotify.session_user_name($session)}."
@@ -30,6 +30,7 @@ module Spotify
30
30
 
31
31
  begin
32
32
  ffi_lib [LIBSPOTIFY_BIN, 'spotify', 'libspotify', '/Library/Frameworks/libspotify.framework/libspotify']
33
+ ffi_convention :stdcall if FFI::Platform.windows?
33
34
  rescue LoadError
34
35
  puts <<-ERROR.gsub(/^ */, '')
35
36
  Failed to load the `libspotify` library. It is possible that the libspotify gem
@@ -1,6 +1,8 @@
1
1
  require "ffi"
2
2
 
3
+ # @see http://github.com/ffi/ffi
3
4
  module FFI
5
+ # Superclass for FFI::Pointer.
4
6
  class AbstractMemory
5
7
  unless method_defined?(:read_size_t)
6
8
  type = FFI.find_type(:size_t)
@@ -13,6 +13,9 @@ module Spotify
13
13
  include Enumerable
14
14
 
15
15
  class << self
16
+ # Releases the given subscribers structure if it is not null.
17
+ #
18
+ # @param [FFI::Pointer] pointer pointing to a subscribers struct
16
19
  def release(pointer)
17
20
  unless pointer.null?
18
21
  pointer = type_class.new(pointer)
@@ -1,4 +1,6 @@
1
1
  module Spotify
2
+ # Spotify::TypeSafety checks all values coming in and makes sure
3
+ # they are of an instance of the correct {#type_class}.
2
4
  module TypeSafety
3
5
  # Convert given value to native value, with type checking.
4
6
  #
@@ -1,4 +1,7 @@
1
1
  module Spotify
2
+ # ByteStrings are for strings that store any binary data, not
3
+ # just regular NULL-terminated strings. It is used for the Spotify
4
+ # application key.
2
5
  module ByteString
3
6
  extend FFI::DataConverter
4
7
  native_type FFI::Type::POINTER
@@ -9,25 +9,29 @@ class << Spotify::API
9
9
  # @example failing to retrieve a value
10
10
  # Spotify.enum_value!(:moo, "connection rule") # => ArgumentError, invalid connection rule: :moo
11
11
  #
12
+ # @api public
12
13
  # @param [Symbol] symbol
13
14
  # @param [#to_s] type used as error message when the symbol does not resolve
14
15
  # @raise [ArgumentError] when the symbol does not exist as an enum value
16
+ # @return [Integer]
15
17
  def enum_value!(symbol, type)
16
18
  enum_value(symbol) or raise ArgumentError, "invalid #{type}: #{symbol}"
17
19
  end
18
20
 
19
21
  # @see platform
22
+ # @api public
20
23
  # @return [Boolean] true if on Linux
21
24
  def linux?
22
25
  platform == :linux
23
26
  end
24
27
 
28
+ # @api public
25
29
  # @return [Symbol] platform as either :mac, :windows, or :linux
26
30
  def platform
27
31
  case FFI::Platform::OS
28
32
  when /darwin/ then :mac
29
33
  when /linux/ then :linux
30
- when /mswin/ then :windows
34
+ when /windows/ then :windows
31
35
  else
32
36
  $stderr.puts "[WARN] You are running the Spotify gem on an unknown platform. (#{__FILE__}:#{__LINE__})"
33
37
  $stderr.puts "[WARN] Platform: #{FFI::Platform::OS}"
@@ -1,7 +1,7 @@
1
1
  module Spotify
2
2
  # @note See README for versioning policy.
3
3
  # @return [String] Spotify gem version.
4
- VERSION = '12.5.2'
4
+ VERSION = '12.5.3'
5
5
 
6
6
  # @return [String] Compatible libspotify API version.
7
7
  API_VERSION = '12.1.51'
@@ -75,6 +75,7 @@ describe Spotify::ManagedPointer do
75
75
  describe "garbage collection", :engine => "ruby" do
76
76
  module Spotify
77
77
  class << API
78
+ # Required by all ManagedPointers.
78
79
  def bogus_add_ref(pointer)
79
80
  end
80
81
 
@@ -89,14 +90,12 @@ describe Spotify::ManagedPointer do
89
90
  let(:my_pointer) { FFI::Pointer.new(1) }
90
91
 
91
92
  it "should work" do
92
- api.stub(:bogus_add_ref)
93
-
94
93
  # GC tests are a bit funky, but as long as we garbage_release at least once, then
95
94
  # we can assume our GC works properly, but up the stakes just for the sake of it
96
95
  api.should_receive(:bogus_release).at_least(1).times
97
96
 
98
- 5.times { Spotify::Bogus.retaining_class.new(FFI::Pointer.new(1)) }
99
- 5.times { GC.start; sleep 0.01 }
97
+ 10.times { Spotify::Bogus.new(FFI::Pointer.new(1)) }
98
+ 10.times { GC.start; sleep 0.01 }
100
99
  end
101
100
  end
102
101
 
@@ -3,7 +3,7 @@ require './lib/spotify/version'
3
3
 
4
4
  Gem::Specification.new do |gem|
5
5
  gem.name = 'spotify'
6
- gem.summary = 'Low-level Ruby bindings for libspotify'
6
+ gem.summary = 'Low-level Ruby bindings for libspotify, the official Spotify C API'
7
7
 
8
8
  gem.homepage = 'https://github.com/Burgestrand/spotify'
9
9
  gem.authors = ["Kim Burgestrand"]
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: spotify
3
3
  version: !ruby/object:Gem::Version
4
- version: 12.5.2
4
+ version: 12.5.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - Kim Burgestrand
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2013-06-25 00:00:00.000000000 Z
11
+ date: 2013-11-09 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: ffi
@@ -211,10 +211,10 @@ required_rubygems_version: !ruby/object:Gem::Requirement
211
211
  version: '0'
212
212
  requirements: []
213
213
  rubyforge_project:
214
- rubygems_version: 2.0.3
214
+ rubygems_version: 2.1.10
215
215
  signing_key:
216
216
  specification_version: 4
217
- summary: Low-level Ruby bindings for libspotify
217
+ summary: Low-level Ruby bindings for libspotify, the official Spotify C API
218
218
  test_files:
219
219
  - spec/bench_helper.rb
220
220
  - spec/benchmarks/managed_pointer_bench.rb