spotify 12.5.3 → 12.6.0

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.
Files changed (104) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +2 -0
  3. data/.travis.yml +20 -5
  4. data/CHANGELOG.md +29 -1
  5. data/Gemfile +5 -0
  6. data/MIT-LICENSE +21 -0
  7. data/README.markdown +75 -50
  8. data/Rakefile +1 -1
  9. data/examples/example-audio_delivery_speed.rb +48 -0
  10. data/examples/{audio-stream_example.rb → example-audio_stream.rb} +14 -29
  11. data/examples/example-console.rb +9 -0
  12. data/examples/example-listing_playlists.rb +89 -0
  13. data/examples/example-loading_object.rb +25 -0
  14. data/examples/example-random_related_artists.rb +53 -0
  15. data/examples/support.rb +106 -0
  16. data/lib/spotify.rb +36 -55
  17. data/lib/spotify/api.rb +54 -26
  18. data/lib/spotify/api/album.rb +45 -2
  19. data/lib/spotify/api/album_browse.rb +81 -3
  20. data/lib/spotify/api/artist.rb +21 -2
  21. data/lib/spotify/api/artist_browse.rb +121 -3
  22. data/lib/spotify/api/error.rb +5 -1
  23. data/lib/spotify/api/image.rb +72 -6
  24. data/lib/spotify/api/inbox.rb +33 -4
  25. data/lib/spotify/api/link.rb +117 -4
  26. data/lib/spotify/api/miscellaneous.rb +12 -0
  27. data/lib/spotify/api/playlist.rb +321 -16
  28. data/lib/spotify/api/playlist_container.rb +168 -9
  29. data/lib/spotify/api/search.rb +156 -3
  30. data/lib/spotify/api/session.rb +390 -26
  31. data/lib/spotify/api/toplist_browse.rb +74 -3
  32. data/lib/spotify/api/track.rb +134 -4
  33. data/lib/spotify/api/user.rb +18 -2
  34. data/lib/spotify/api_helpers.rb +47 -0
  35. data/lib/spotify/data_converters.rb +7 -0
  36. data/lib/spotify/{types → data_converters}/best_effort_string.rb +1 -1
  37. data/lib/spotify/{types → data_converters}/byte_string.rb +0 -0
  38. data/lib/spotify/data_converters/country_code.rb +30 -0
  39. data/lib/spotify/{types → data_converters}/image_id.rb +1 -1
  40. data/lib/spotify/{type_safety.rb → data_converters/type_safety.rb} +0 -0
  41. data/lib/spotify/{types → data_converters}/utf8_string.rb +2 -2
  42. data/lib/spotify/{types → data_converters}/utf8_string_pointer.rb +2 -2
  43. data/lib/spotify/error.rb +180 -47
  44. data/lib/spotify/managed_pointer.rb +32 -12
  45. data/lib/spotify/monkey_patches/ffi_buffer.rb +11 -0
  46. data/lib/spotify/monkey_patches/ffi_enums.rb +4 -0
  47. data/lib/spotify/monkey_patches/ffi_pointer.rb +1 -0
  48. data/lib/spotify/structs.rb +4 -0
  49. data/lib/spotify/structs/session_callbacks.rb +97 -26
  50. data/lib/spotify/structs/session_config.rb +1 -1
  51. data/lib/spotify/structs/subscribers.rb +4 -3
  52. data/lib/spotify/types.rb +104 -5
  53. data/lib/spotify/{objects → types}/album.rb +0 -0
  54. data/lib/spotify/{objects → types}/album_browse.rb +0 -0
  55. data/lib/spotify/{objects → types}/artist.rb +0 -0
  56. data/lib/spotify/{objects → types}/artist_browse.rb +0 -0
  57. data/lib/spotify/{objects → types}/image.rb +0 -0
  58. data/lib/spotify/{objects → types}/inbox.rb +0 -0
  59. data/lib/spotify/{objects → types}/link.rb +0 -0
  60. data/lib/spotify/{objects → types}/playlist.rb +0 -0
  61. data/lib/spotify/{objects → types}/playlist_container.rb +0 -0
  62. data/lib/spotify/{objects → types}/search.rb +0 -0
  63. data/lib/spotify/{objects → types}/session.rb +0 -0
  64. data/lib/spotify/{objects → types}/toplist_browse.rb +0 -0
  65. data/lib/spotify/{objects → types}/track.rb +0 -0
  66. data/lib/spotify/{objects → types}/user.rb +0 -0
  67. data/lib/spotify/util.rb +38 -35
  68. data/lib/spotify/version.rb +1 -1
  69. data/spec/spec_helper.rb +24 -13
  70. data/spec/spotify/api/image_spec.rb +32 -0
  71. data/spec/spotify/api/inbox_spec.rb +34 -0
  72. data/spec/spotify/api/link_spec.rb +40 -0
  73. data/spec/spotify/api/playlist_spec.rb +99 -0
  74. data/spec/spotify/api/playlistcontainer_spec.rb +82 -0
  75. data/spec/spotify/api/session_spec.rb +97 -0
  76. data/spec/spotify/api/track_spec.rb +29 -0
  77. data/spec/spotify/api_error_spec.rb +55 -0
  78. data/spec/spotify/api_spec.rb +17 -11
  79. data/spec/spotify/{types → data_converters}/best_effort_string_spec.rb +4 -4
  80. data/spec/spotify/{types → data_converters}/byte_string_spec.rb +0 -0
  81. data/spec/spotify/data_converters/country_code_spec.rb +16 -0
  82. data/spec/spotify/{types → data_converters}/image_id_spec.rb +1 -1
  83. data/spec/spotify/{type_safety_spec.rb → data_converters/type_safety_spec.rb} +0 -0
  84. data/spec/spotify/{types → data_converters}/utf8_string_pointer_spec.rb +0 -0
  85. data/spec/spotify/{types → data_converters}/utf8_string_spec.rb +1 -1
  86. data/spec/spotify/{api/functions_spec.rb → functions_spec.rb} +2 -0
  87. data/spec/spotify/managed_pointer_spec.rb +13 -13
  88. data/spec/spotify/structs/subscribers_spec.rb +5 -3
  89. data/spec/spotify/{defines_spec.rb → types_spec.rb} +16 -3
  90. data/spec/spotify/util_spec.rb +24 -0
  91. data/spec/spotify_spec.rb +74 -0
  92. data/spec/support/spotify_util.rb +6 -2
  93. data/spec/support/spy_output.rb +16 -0
  94. data/spotify.gemspec +4 -2
  95. metadata +111 -71
  96. data/examples/README.md +0 -15
  97. data/examples/console_example.rb +0 -22
  98. data/examples/example_support.rb +0 -66
  99. data/examples/loading-object_example.rb +0 -43
  100. data/examples/logging-in_example.rb +0 -58
  101. data/lib/spotify/defines.rb +0 -109
  102. data/lib/spotify/objects.rb +0 -17
  103. data/spec/spotify/enums_spec.rb +0 -9
  104. data/spec/spotify/spotify_spec.rb +0 -69
@@ -1,43 +0,0 @@
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
- $session = Support.create_session(config)
17
-
18
- $logger.info "Created! Logging in."
19
- Spotify.session_login($session, $username, $password, false, $blob)
20
-
21
- $logger.info "Log in requested. Waiting forever until logged in."
22
- Support.poll($session) { Spotify.session_connectionstate($session) == :logged_in }
23
-
24
- $logger.info "Logged in as #{Spotify.session_user_name($session)}."
25
-
26
- track_uri = Support.prompt("Please enter an track URI")
27
- link = Spotify.link_create_from_string(track_uri)
28
-
29
- if link.null?
30
- $logger.error "Invalid URI. Aborting."
31
- abort
32
- elsif (link_type = Spotify.link_type(link)) != :track
33
- $logger.error "Was #{link_type} URI. Needs track. Aborting."
34
- abort
35
- else
36
- track = Spotify.link_as_track(link)
37
- end
38
-
39
- $logger.info "Attempting to load track. Waiting forever until successful."
40
- Support.poll($session) { Spotify.track_is_loaded(track) }
41
- $logger.info "Track loaded."
42
-
43
- puts Spotify.track_name(track)
@@ -1,58 +0,0 @@
1
- #!/usr/bin/env ruby
2
- # encoding: utf-8
3
-
4
- require_relative "example_support"
5
-
6
- #
7
- # Global callback procs.
8
- #
9
- # They are global variables to protect from ever being garbage collected.
10
- #
11
- # You must not allow the callbacks to ever be garbage collected, or libspotify
12
- # will hold information about callbacks that no longer exist, and crash upon
13
- # calling the first missing callback. This is *very* important!
14
-
15
- $session_callbacks = {
16
- log_message: lambda do |session, message|
17
- $logger.info('session (log message)') { message }
18
- end,
19
-
20
- logged_in: lambda do |session, error|
21
- $logger.info('session (logged in)') { Spotify::Error.explain(error) }
22
- end,
23
-
24
- logged_out: lambda do |session|
25
- $logger.info('session (logged out)') { 'logged out!' }
26
- end,
27
-
28
- credentials_blob_updated: lambda do |session, blob|
29
- $logger.info('session (blob)') { blob }
30
- end
31
- }
32
-
33
- #
34
- # Main work code.
35
- #
36
-
37
- # You can read about what these session configuration options do in the
38
- # libspotify documentation:
39
- # https://developer.spotify.com/technologies/libspotify/docs/12.1.45/structsp__session__config.html
40
- config = Spotify::SessionConfig.new({
41
- api_version: Spotify::API_VERSION.to_i,
42
- application_key: $appkey,
43
- cache_location: ".spotify/",
44
- settings_location: ".spotify/",
45
- user_agent: "spotify for ruby",
46
- callbacks: Spotify::SessionCallbacks.new($session_callbacks),
47
- })
48
-
49
- $logger.info "Creating session."
50
- $session = Support.create_session(config)
51
-
52
- $logger.info "Created! Logging in."
53
- Spotify.session_login($session, $username, $password, false, $blob)
54
-
55
- $logger.info "Log in requested. Waiting forever until logged in."
56
- Support.poll($session) { Spotify.session_connectionstate($session) == :logged_in }
57
-
58
- $logger.info "Logged in as #{Spotify.session_user_name($session)}."
@@ -1,109 +0,0 @@
1
- module Spotify
2
- class API
3
- typedef :pointer, :frames
4
- typedef :pointer, :userdata
5
- typedef :pointer, :array
6
-
7
- #
8
- # Error
9
- #
10
- enum :error, [:ok, 0,
11
- :bad_api_version, :api_initialization_failed, :track_not_playable,
12
-
13
- :bad_application_key, 5,
14
- :bad_username_or_password, :user_banned,
15
- :unable_to_contact_server, :client_too_old, :other_permanent,
16
- :bad_user_agent, :missing_callback, :invalid_indata,
17
- :index_out_of_range, :user_needs_premium, :other_transient,
18
- :is_loading, :no_stream_available, :permission_denied,
19
- :inbox_is_full, :no_cache, :no_such_user, :no_credentials,
20
- :network_disabled, :invalid_device_id, :cant_open_trace_file,
21
- :application_banned,
22
-
23
- :offline_too_many_tracks, 31,
24
- :offline_disk_cache, :offline_expired, :offline_not_allowed,
25
- :offline_license_lost, :offline_license_error,
26
-
27
- :lastfm_auth_error, 39,
28
- :invalid_argument, :system_failure]
29
-
30
- #
31
- # Audio
32
- #
33
- enum :sampletype, [:int16] # int16_native_endian
34
- enum :bitrate, %w(160k 320k 96k).map(&:to_sym)
35
-
36
- #
37
- # Session
38
- #
39
- enum :social_provider, [:spotify, :facebook, :lastfm]
40
- enum :scrobbling_state, [:use_global_setting, :local_enabled, :local_disabled, :global_enabled, :global_disabled]
41
- enum :connectionstate, [:logged_out, :logged_in, :disconnected, :undefined, :offline]
42
- enum :connection_type, [:unknown, :none, :mobile, :mobile_roaming, :wifi, :wired]
43
- enum :connection_rules, [:network , 0x1,
44
- :network_if_roaming , 0x2,
45
- :allow_sync_over_mobile, 0x4,
46
- :allow_sync_over_wifi , 0x8]
47
-
48
- #
49
- # Image
50
- #
51
- callback :image_loaded_cb, [ Image.retaining_class, :userdata ], :void
52
- enum :imageformat, [:unknown, -1, :jpeg]
53
- enum :image_size, [ :normal, :small, :large ]
54
-
55
- #
56
- # Link
57
- #
58
- enum :linktype, [:invalid, :track, :album, :artist, :search,
59
- :playlist, :profile, :starred, :localtrack, :image]
60
-
61
- #
62
- # Track
63
- #
64
- enum :availability, [:unavailable, :available, :not_streamable, :banned_by_artist]
65
- typedef :availability, :track_availability # for automated testing
66
- enum :track_offline_status, [:no, :waiting, :downloading, :done, :error, :done_expired, :limit_exceeded, :done_resync]
67
-
68
- #
69
- # Album
70
- #
71
- callback :albumbrowse_complete_cb, [AlbumBrowse.retaining_class, :userdata], :void
72
- enum :albumtype, [:album, :single, :compilation, :unknown]
73
-
74
- #
75
- # Artist browsing
76
- #
77
- callback :artistbrowse_complete_cb, [ArtistBrowse.retaining_class, :userdata], :void
78
- enum :artistbrowse_type, [:full, :no_tracks, :no_albums]
79
-
80
- #
81
- # Search
82
- #
83
- callback :search_complete_cb, [Search.retaining_class, :userdata], :void
84
- enum :search_type, [:standard, :suggest]
85
-
86
- #
87
- # Playlist
88
- #
89
- enum :playlist_type, [:playlist, :start_folder, :end_folder, :placeholder]
90
- enum :playlist_offline_status, [:no, :yes, :downloading, :waiting]
91
-
92
- #
93
- # User
94
- #
95
- enum :relation_type, [:unknown, :none, :unidirectional, :bidirectional]
96
-
97
- #
98
- # Toplist
99
- #
100
- callback :toplistbrowse_complete_cb, [ToplistBrowse.retaining_class, :userdata], :void
101
- enum :toplisttype, [:artists, :albums, :tracks]
102
- enum :toplistregion, [:everywhere, :user]
103
-
104
- #
105
- # Inbox
106
- #
107
- callback :inboxpost_complete_cb, [Inbox.retaining_class, :userdata], :void
108
- end
109
- end
@@ -1,17 +0,0 @@
1
- require 'spotify/type_safety'
2
- require 'spotify/managed_pointer'
3
-
4
- require 'spotify/objects/album'
5
- require 'spotify/objects/album_browse'
6
- require 'spotify/objects/artist'
7
- require 'spotify/objects/artist_browse'
8
- require 'spotify/objects/image'
9
- require 'spotify/objects/inbox'
10
- require 'spotify/objects/link'
11
- require 'spotify/objects/playlist'
12
- require 'spotify/objects/playlist_container'
13
- require 'spotify/objects/search'
14
- require 'spotify/objects/session'
15
- require 'spotify/objects/toplist_browse'
16
- require 'spotify/objects/track'
17
- require 'spotify/objects/user'
@@ -1,9 +0,0 @@
1
- describe "Spotify enums" do
2
- describe "audio sample types" do
3
- Spotify.enum_type(:sampletype).symbols.each do |symbol|
4
- specify "#{symbol} has a reader in FFI" do
5
- FFI::Pointer.new(1).should respond_to "read_array_of_#{symbol}"
6
- end
7
- end
8
- end
9
- end
@@ -1,69 +0,0 @@
1
- describe Spotify do
2
- describe "VERSION" do
3
- it "is defined" do
4
- defined?(Spotify::VERSION).should eq "constant"
5
- end
6
-
7
- it "is the same version as in api.h" do
8
- spotify_version = API_H_SRC.match(/#define\s+SPOTIFY_API_VERSION\s+(\d+)/)[1]
9
- Spotify::API_VERSION.to_i.should eq spotify_version.to_i
10
- end
11
- end
12
-
13
- describe "proxying" do
14
- it "responds to the spotify methods" do
15
- Spotify.should respond_to :error_message
16
- end
17
- end
18
-
19
- describe ".try" do
20
- it "raises an error when the result is not OK" do
21
- api.should_receive(:error_example).and_return(:bad_application_key)
22
- expect { Spotify.try(:error_example) }.to raise_error(Spotify::Error, /BAD_APPLICATION_KEY/)
23
- end
24
-
25
- it "does not raise an error when the result is OK" do
26
- api.should_receive(:error_example).and_return(:ok)
27
- Spotify.try(:error_example).should eq :ok
28
- end
29
-
30
- it "does not raise an error when the result is not an error-type" do
31
- result = Object.new
32
- api.should_receive(:error_example).and_return(result)
33
- Spotify.try(:error_example).should eq result
34
- end
35
- end
36
-
37
- describe ".enum_value!" do
38
- it "raises an error if given an invalid enum value" do
39
- expect { Spotify.enum_value!(:moo, "error value") }.to raise_error(ArgumentError)
40
- end
41
-
42
- it "gives back the enum value for that enum" do
43
- Spotify.enum_value!(:ok, "error value").should eq 0
44
- end
45
- end
46
-
47
- describe ".attach_function" do
48
- it "is a retaining class if the method is not creating" do
49
- begin
50
- Spotify::API.attach_function :whatever, [], Spotify::User
51
- rescue FFI::NotFoundError
52
- # expected, this method does not exist
53
- end
54
-
55
- $attached_methods["whatever"][:returns].should eq Spotify::User.retaining_class
56
- end
57
-
58
- it "is a non-retaining class if the method is creating" do
59
- begin
60
- Spotify::API.attach_function :whatever_create, [], Spotify::User
61
- rescue FFI::NotFoundError
62
- # expected, this method does not exist
63
- end
64
-
65
- $attached_methods["whatever_create"][:returns].should be Spotify::User
66
- $attached_methods["whatever_create"][:returns].should_not be Spotify::User.retaining_class
67
- end
68
- end
69
- end