spotify 12.5.1 → 12.5.2
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 +4 -4
- data/CHANGELOG.md +10 -1
- data/README.markdown +1 -1
- data/examples/{audio-stream.rb → audio-stream_example.rb} +5 -32
- data/examples/console_example.rb +25 -0
- data/examples/example_support.rb +46 -0
- data/examples/loading-object_example.rb +46 -0
- data/examples/{logging-in.rb → logging-in_example.rb} +3 -33
- data/lib/spotify/api/link.rb +1 -1
- data/lib/spotify/types.rb +1 -0
- data/lib/spotify/types/best_effort_string.rb +21 -0
- data/lib/spotify/version.rb +1 -1
- data/spec/spec_helper.rb +16 -0
- data/spec/spotify/types/best_effort_string_spec.rb +22 -0
- metadata +10 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 981b598f43ddd1bb8c920bc52227349cc3c38983
|
4
|
+
data.tar.gz: fcc1deabbf3d31c131c870edd7a08366f0267134
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 8d7b1a66718c08753571a3cbd0d720fd9c34bd7692baeecf9304731ff7b0181dfda43d6c4cc050635672e8beebe9e89780cc3d86addc28b01615fb236d3a381c
|
7
|
+
data.tar.gz: 7876ab5a93a7316f087a949a8c32e26218a4b969d4cb0641374c610ab2cae9caa2f64fa32950a649befccf4d8794ce7ce38237c97b9f0ca3988ac31c8c0ea091
|
data/CHANGELOG.md
CHANGED
@@ -1,6 +1,14 @@
|
|
1
1
|
[HEAD][]
|
2
2
|
-----------
|
3
3
|
|
4
|
+
[v12.5.2][]
|
5
|
+
-----------
|
6
|
+
|
7
|
+
- [5245d932b] #link_create_from_string now accepts non-UTF8
|
8
|
+
- [349dfdc61] #link_create_from_string now accepts strings with NULL-bytes in them (it clips the string)
|
9
|
+
- [349dfdc61] #link_create_from_string now accepts empty strings without crashing
|
10
|
+
- [ef7ae9390] #link_create_from_string no longer throws a warning on UTF-8
|
11
|
+
|
4
12
|
[v12.5.1][]
|
5
13
|
-----------
|
6
14
|
|
@@ -190,8 +198,9 @@ v0.0.0
|
|
190
198
|
------
|
191
199
|
- release to register rubygems.org name
|
192
200
|
|
193
|
-
[HEAD]: https://github.com/Burgestrand/spotify/compare/v12.5.
|
201
|
+
[HEAD]: https://github.com/Burgestrand/spotify/compare/v12.5.2...HEAD
|
194
202
|
|
203
|
+
[v12.5.2]: https://github.com/Burgestrand/spotify/compare/v12.5.1...v12.5.2
|
195
204
|
[v12.5.1]: https://github.com/Burgestrand/spotify/compare/v12.5.0...v12.5.1
|
196
205
|
[v12.5.0]: https://github.com/Burgestrand/spotify/compare/v12.4.0...v12.5.0
|
197
206
|
[v12.4.0]: https://github.com/Burgestrand/spotify/compare/v12.3.0...v12.4.0
|
data/README.markdown
CHANGED
@@ -9,7 +9,7 @@ with it in an API is awesome. libspotify itself is however written in C, making
|
|
9
9
|
it unavailable or cumbersome to use for many developers.
|
10
10
|
|
11
11
|
This project aims to allow Ruby developers access to all of the libspotify C API,
|
12
|
-
without needing to reach down to C. However, to use this library to
|
12
|
+
without needing to reach down to C. However, to use this library to its full extent
|
13
13
|
you will need to learn how to use the Ruby FFI API.
|
14
14
|
|
15
15
|
The Spotify gem has:
|
@@ -1,39 +1,11 @@
|
|
1
1
|
#!/usr/bin/env ruby
|
2
2
|
# encoding: utf-8
|
3
3
|
|
4
|
-
|
5
|
-
|
6
|
-
require "logger"
|
4
|
+
require_relative "example_support"
|
5
|
+
|
7
6
|
require "json"
|
8
|
-
require "pry"
|
9
7
|
require "plaything"
|
10
8
|
|
11
|
-
Thread.abort_on_exception = true
|
12
|
-
|
13
|
-
# We use a logger to print some information on when things are happening.
|
14
|
-
$logger = Logger.new($stderr)
|
15
|
-
$logger.level = Logger::INFO
|
16
|
-
|
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)
|
24
|
-
end
|
25
|
-
sleep(0.1)
|
26
|
-
end
|
27
|
-
end
|
28
|
-
|
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\""
|
34
|
-
end
|
35
|
-
end
|
36
|
-
|
37
9
|
def play_track(uri)
|
38
10
|
link = Spotify.link_create_from_string(uri)
|
39
11
|
track = Spotify.link_as_track(link)
|
@@ -117,6 +89,7 @@ $session_callbacks = {
|
|
117
89
|
else
|
118
90
|
frames = FrameReader.new(format[:channels], format[:sample_type], num_frames, frames)
|
119
91
|
consumed_frames = plaything.stream(frames, format.to_h)
|
92
|
+
$logger.info("session (player)") { "#{format.to_h}" }
|
120
93
|
$logger.debug("session (player)") { "music delivery #{consumed_frames} of #{num_frames}" }
|
121
94
|
consumed_frames
|
122
95
|
end
|
@@ -138,7 +111,7 @@ $session_callbacks = {
|
|
138
111
|
# https://developer.spotify.com/technologies/libspotify/docs/12.1.45/structsp__session__config.html
|
139
112
|
config = Spotify::SessionConfig.new({
|
140
113
|
api_version: Spotify::API_VERSION.to_i,
|
141
|
-
application_key:
|
114
|
+
application_key: $appkey,
|
142
115
|
cache_location: ".spotify/",
|
143
116
|
settings_location: ".spotify/",
|
144
117
|
tracefile: "spotify_tracefile.txt",
|
@@ -153,7 +126,7 @@ FFI::MemoryPointer.new(Spotify::Session) do |ptr|
|
|
153
126
|
end
|
154
127
|
|
155
128
|
$logger.info "Created! Logging in."
|
156
|
-
Spotify.session_login($session,
|
129
|
+
Spotify.session_login($session, $username, $password, false, nil)
|
157
130
|
|
158
131
|
$logger.info "Log in requested. Waiting forever until logged in."
|
159
132
|
poll($session) { Spotify.session_connectionstate($session) == :logged_in }
|
@@ -0,0 +1,25 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
# encoding: utf-8
|
3
|
+
|
4
|
+
require_relative "example_support"
|
5
|
+
|
6
|
+
config = Spotify::SessionConfig.new({
|
7
|
+
api_version: Spotify::API_VERSION.to_i,
|
8
|
+
application_key: $appkey,
|
9
|
+
cache_location: ".spotify/",
|
10
|
+
settings_location: ".spotify/",
|
11
|
+
user_agent: "spotify for ruby",
|
12
|
+
callbacks: nil,
|
13
|
+
})
|
14
|
+
|
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
|
20
|
+
|
21
|
+
$logger.info "Created! Logging in."
|
22
|
+
Spotify.session_login($session, $username, $password, false, nil)
|
23
|
+
|
24
|
+
$logger.info "Logged in! Entering interactive session…"
|
25
|
+
binding.pry
|
@@ -0,0 +1,46 @@
|
|
1
|
+
require "bundler/setup"
|
2
|
+
require "spotify"
|
3
|
+
require "logger"
|
4
|
+
require "pry"
|
5
|
+
|
6
|
+
# Kill main thread if any other thread dies.
|
7
|
+
Thread.abort_on_exception = true
|
8
|
+
|
9
|
+
# We use a logger to print some information on when things are happening.
|
10
|
+
$logger = Logger.new($stderr)
|
11
|
+
$logger.level = Logger::INFO
|
12
|
+
|
13
|
+
#
|
14
|
+
# Some utility.
|
15
|
+
#
|
16
|
+
|
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)
|
24
|
+
end
|
25
|
+
sleep(0.1)
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
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'"
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
# Ask the user for input with a prompt explaining what kind of input.
|
38
|
+
def prompt(message)
|
39
|
+
print "#{message}: "
|
40
|
+
gets.chomp
|
41
|
+
end
|
42
|
+
|
43
|
+
# Load the configuration.
|
44
|
+
$appkey = IO.read("./spotify_appkey.key", encoding: "BINARY")
|
45
|
+
$username = env("SPOTIFY_USERNAME")
|
46
|
+
$password = env("SPOTIFY_PASSWORD")
|
@@ -0,0 +1,46 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
# encoding: utf-8
|
3
|
+
|
4
|
+
require_relative "example_support"
|
5
|
+
|
6
|
+
config = Spotify::SessionConfig.new({
|
7
|
+
api_version: Spotify::API_VERSION.to_i,
|
8
|
+
application_key: $appkey,
|
9
|
+
cache_location: ".spotify/",
|
10
|
+
settings_location: ".spotify/",
|
11
|
+
user_agent: "spotify for ruby",
|
12
|
+
callbacks: nil,
|
13
|
+
})
|
14
|
+
|
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
|
20
|
+
|
21
|
+
$logger.info "Created! Logging in."
|
22
|
+
Spotify.session_login($session, $username, $password, false, nil)
|
23
|
+
|
24
|
+
$logger.info "Log in requested. Waiting forever until logged in."
|
25
|
+
poll($session) { Spotify.session_connectionstate($session) == :logged_in }
|
26
|
+
|
27
|
+
$logger.info "Logged in as #{Spotify.session_user_name($session)}."
|
28
|
+
|
29
|
+
track_uri = prompt("Please enter an track URI")
|
30
|
+
link = Spotify.link_create_from_string(track_uri)
|
31
|
+
|
32
|
+
if link.null?
|
33
|
+
$logger.error "Invalid URI. Aborting."
|
34
|
+
abort
|
35
|
+
elsif (link_type = Spotify.link_type(link)) != :track
|
36
|
+
$logger.error "Was #{link_type} URI. Needs track. Aborting."
|
37
|
+
abort
|
38
|
+
else
|
39
|
+
track = Spotify.link_as_track(link)
|
40
|
+
end
|
41
|
+
|
42
|
+
$logger.info "Attempting to load track. Waiting forever until successful."
|
43
|
+
poll($session) { Spotify.track_is_loaded(track) }
|
44
|
+
$logger.info "Track loaded."
|
45
|
+
|
46
|
+
puts Spotify.track_name(track)
|
@@ -1,36 +1,7 @@
|
|
1
1
|
#!/usr/bin/env ruby
|
2
2
|
# encoding: utf-8
|
3
3
|
|
4
|
-
|
5
|
-
require "spotify"
|
6
|
-
require "logger"
|
7
|
-
|
8
|
-
# We use a logger to print some information on when things are happening.
|
9
|
-
$logger = Logger.new($stderr)
|
10
|
-
|
11
|
-
#
|
12
|
-
# Some utility.
|
13
|
-
#
|
14
|
-
|
15
|
-
# libspotify supports callbacks, but they are not useful for waiting on
|
16
|
-
# operations (how they fire can be strange at times, and sometimes they
|
17
|
-
# might not fire at all). As a result, polling is the way to go.
|
18
|
-
def poll(session)
|
19
|
-
until yield
|
20
|
-
FFI::MemoryPointer.new(:int) do |ptr|
|
21
|
-
Spotify.session_process_events(session, ptr)
|
22
|
-
end
|
23
|
-
sleep(0.01)
|
24
|
-
end
|
25
|
-
end
|
26
|
-
|
27
|
-
# For making sure fetching configuration options fail with a useful error
|
28
|
-
# message when running the examples.
|
29
|
-
def env(name)
|
30
|
-
ENV.fetch(name) do
|
31
|
-
raise "Missing ENV['#{name}']. Please: export #{name}='your value'"
|
32
|
-
end
|
33
|
-
end
|
4
|
+
require_relative "example_support"
|
34
5
|
|
35
6
|
#
|
36
7
|
# Global callback procs.
|
@@ -64,10 +35,9 @@ $session_callbacks = {
|
|
64
35
|
# https://developer.spotify.com/technologies/libspotify/docs/12.1.45/structsp__session__config.html
|
65
36
|
config = Spotify::SessionConfig.new({
|
66
37
|
api_version: Spotify::API_VERSION.to_i,
|
67
|
-
application_key:
|
38
|
+
application_key: $appkey,
|
68
39
|
cache_location: ".spotify/",
|
69
40
|
settings_location: ".spotify/",
|
70
|
-
tracefile: "spotify_tracefile.txt",
|
71
41
|
user_agent: "spotify for ruby",
|
72
42
|
callbacks: Spotify::SessionCallbacks.new($session_callbacks),
|
73
43
|
})
|
@@ -81,7 +51,7 @@ FFI::MemoryPointer.new(Spotify::Session) do |ptr|
|
|
81
51
|
end
|
82
52
|
|
83
53
|
$logger.info "Created! Logging in."
|
84
|
-
Spotify.session_login($session,
|
54
|
+
Spotify.session_login($session, $username, $password, false, nil)
|
85
55
|
|
86
56
|
$logger.info "Log in requested. Waiting forever until logged in."
|
87
57
|
poll($session) { Spotify.session_connectionstate($session) == :logged_in }
|
data/lib/spotify/api/link.rb
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
module Spotify
|
2
2
|
class API
|
3
3
|
# @!group Link
|
4
|
-
attach_function :link_create_from_string, [
|
4
|
+
attach_function :link_create_from_string, [ BestEffortString ], Link
|
5
5
|
attach_function :link_create_from_track, [ Track, :int ], Link
|
6
6
|
attach_function :link_create_from_album, [ Album ], Link
|
7
7
|
attach_function :link_create_from_artist, [ Artist ], Link
|
data/lib/spotify/types.rb
CHANGED
@@ -0,0 +1,21 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
module Spotify
|
3
|
+
# A regular string type, ending at the first NULL byte.
|
4
|
+
#
|
5
|
+
# Regular FFI :string raises errors when it encounters NULLs.
|
6
|
+
module BestEffortString
|
7
|
+
extend FFI::DataConverter
|
8
|
+
native_type FFI::Type::STRING
|
9
|
+
|
10
|
+
class << self
|
11
|
+
# Extracts all of the string up until the first NULL byte.
|
12
|
+
#
|
13
|
+
# @param [String, nil] value
|
14
|
+
# @param ctx
|
15
|
+
# @return [String] value, up until the first NULL byte
|
16
|
+
def to_native(value, ctx)
|
17
|
+
value && value.dup.force_encoding("BINARY")[/[^\x00]*/n]
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
data/lib/spotify/version.rb
CHANGED
data/spec/spec_helper.rb
CHANGED
@@ -2,6 +2,7 @@
|
|
2
2
|
require "rbgccxml"
|
3
3
|
require "rspec"
|
4
4
|
require "pry"
|
5
|
+
require "stringio"
|
5
6
|
|
6
7
|
require "spec/support/hook_spotify"
|
7
8
|
require "spec/support/spotify_util"
|
@@ -27,4 +28,19 @@ RSpec.configure do |config|
|
|
27
28
|
required_version = Gem::Requirement.new(requirement)
|
28
29
|
! required_version.satisfied_by?(ruby_version)
|
29
30
|
end)
|
31
|
+
|
32
|
+
config.around(:each) do |test|
|
33
|
+
stderr, $stderr = $stderr, StringIO.new("")
|
34
|
+
begin
|
35
|
+
test.run
|
36
|
+
$stderr.rewind
|
37
|
+
warnings = $stderr.read
|
38
|
+
if warnings =~ %r"lib/spotify"
|
39
|
+
stderr.write(warnings)
|
40
|
+
raise "#{example.description.inspect} caused a warning, #{warnings.inspect}"
|
41
|
+
end
|
42
|
+
ensure
|
43
|
+
$stderr = stderr
|
44
|
+
end
|
45
|
+
end
|
30
46
|
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
describe Spotify::BestEffortString do
|
3
|
+
describe "#to_native" do
|
4
|
+
it "simply reads a null-terminated string" do
|
5
|
+
source = "hello wörld"
|
6
|
+
string = Spotify::BestEffortString.to_native(source, nil)
|
7
|
+
string.should eq "hello wörld".force_encoding("BINARY")
|
8
|
+
end
|
9
|
+
|
10
|
+
it "cuts the string at the first encountered NULL-byte" do
|
11
|
+
source = "hello\x00wörld".force_encoding("BINARY")
|
12
|
+
string = Spotify::BestEffortString.to_native(source, nil)
|
13
|
+
string.should eq "hello".force_encoding("BINARY")
|
14
|
+
end
|
15
|
+
|
16
|
+
it "treats empty string as empty string, and not null" do
|
17
|
+
source = ""
|
18
|
+
string = Spotify::BestEffortString.to_native(source, nil)
|
19
|
+
string.should eq "".force_encoding("BINARY")
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
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.
|
4
|
+
version: 12.5.2
|
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-
|
11
|
+
date: 2013-06-25 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: ffi
|
@@ -103,8 +103,11 @@ files:
|
|
103
103
|
- Rakefile
|
104
104
|
- examples/.gitignore
|
105
105
|
- examples/README.md
|
106
|
-
- examples/audio-
|
107
|
-
- examples/
|
106
|
+
- examples/audio-stream_example.rb
|
107
|
+
- examples/console_example.rb
|
108
|
+
- examples/example_support.rb
|
109
|
+
- examples/loading-object_example.rb
|
110
|
+
- examples/logging-in_example.rb
|
108
111
|
- lib/spotify.rb
|
109
112
|
- lib/spotify/api.rb
|
110
113
|
- lib/spotify/api/album.rb
|
@@ -152,6 +155,7 @@ files:
|
|
152
155
|
- lib/spotify/structs/subscribers.rb
|
153
156
|
- lib/spotify/type_safety.rb
|
154
157
|
- lib/spotify/types.rb
|
158
|
+
- lib/spotify/types/best_effort_string.rb
|
155
159
|
- lib/spotify/types/byte_string.rb
|
156
160
|
- lib/spotify/types/image_id.rb
|
157
161
|
- lib/spotify/types/utf8_string.rb
|
@@ -173,6 +177,7 @@ files:
|
|
173
177
|
- spec/spotify/structs/subscribers_spec.rb
|
174
178
|
- spec/spotify/structs_spec.rb
|
175
179
|
- spec/spotify/type_safety_spec.rb
|
180
|
+
- spec/spotify/types/best_effort_string_spec.rb
|
176
181
|
- spec/spotify/types/byte_string_spec.rb
|
177
182
|
- spec/spotify/types/image_id_spec.rb
|
178
183
|
- spec/spotify/types/utf8_string_pointer_spec.rb
|
@@ -226,6 +231,7 @@ test_files:
|
|
226
231
|
- spec/spotify/structs/subscribers_spec.rb
|
227
232
|
- spec/spotify/structs_spec.rb
|
228
233
|
- spec/spotify/type_safety_spec.rb
|
234
|
+
- spec/spotify/types/best_effort_string_spec.rb
|
229
235
|
- spec/spotify/types/byte_string_spec.rb
|
230
236
|
- spec/spotify/types/image_id_spec.rb
|
231
237
|
- spec/spotify/types/utf8_string_pointer_spec.rb
|