hallon 0.12.0 → 0.13.0
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGELOG.md +43 -0
- data/Gemfile +3 -1
- data/README.markdown +41 -11
- data/Rakefile +12 -0
- data/examples/audio_driver.rb +55 -0
- data/examples/playing_audio.rb +10 -50
- data/hallon.gemspec +1 -1
- data/lib/hallon.rb +1 -1
- data/lib/hallon/album_browse.rb +22 -11
- data/lib/hallon/artist_browse.rb +64 -33
- data/lib/hallon/audio_driver.rb +138 -0
- data/lib/hallon/audio_queue.rb +110 -0
- data/lib/hallon/enumerator.rb +55 -16
- data/lib/hallon/error.rb +9 -2
- data/lib/hallon/image.rb +6 -5
- data/lib/hallon/link.rb +7 -4
- data/lib/hallon/linkable.rb +27 -0
- data/lib/hallon/observable/player.rb +18 -1
- data/lib/hallon/observable/session.rb +5 -1
- data/lib/hallon/player.rb +180 -54
- data/lib/hallon/playlist.rb +33 -20
- data/lib/hallon/playlist_container.rb +78 -64
- data/lib/hallon/search.rb +51 -33
- data/lib/hallon/session.rb +1 -1
- data/lib/hallon/toplist.rb +36 -18
- data/lib/hallon/track.rb +12 -6
- data/lib/hallon/version.rb +1 -1
- data/spec/hallon/artist_browse_spec.rb +3 -4
- data/spec/hallon/audio_queue_spec.rb +89 -0
- data/spec/hallon/enumerator_spec.rb +50 -25
- data/spec/hallon/error_spec.rb +2 -2
- data/spec/hallon/image_spec.rb +12 -5
- data/spec/hallon/link_spec.rb +8 -9
- data/spec/hallon/linkable_spec.rb +11 -0
- data/spec/hallon/observable/session_spec.rb +4 -0
- data/spec/hallon/player_spec.rb +118 -5
- data/spec/hallon/playlist_container_spec.rb +2 -2
- data/spec/hallon/playlist_spec.rb +32 -37
- data/spec/hallon/search_spec.rb +3 -3
- data/spec/hallon/user_spec.rb +0 -6
- data/spec/spec_helper.rb +10 -0
- data/spec/support/audio_driver_mock.rb +23 -0
- data/spec/support/context_stub_session.rb +5 -0
- data/spec/support/shared_for_linkable_objects.rb +22 -2
- metadata +26 -20
- data/lib/hallon/queue.rb +0 -71
- data/spec/hallon/queue_spec.rb +0 -35
data/CHANGELOG.md
CHANGED
@@ -1,6 +1,47 @@
|
|
1
1
|
Hallon’s Changelog
|
2
2
|
==================
|
3
3
|
|
4
|
+
[HEAD][]
|
5
|
+
------------------
|
6
|
+
|
7
|
+
__Added__
|
8
|
+
|
9
|
+
__Changed__
|
10
|
+
|
11
|
+
__Fixed__
|
12
|
+
|
13
|
+
[v0.13.0][]
|
14
|
+
------------------
|
15
|
+
|
16
|
+
Hallon v0.13.0 brings support for using external audio drivers with
|
17
|
+
the Hallon::Player API. The specification on how to write your own
|
18
|
+
driver is in the README.
|
19
|
+
|
20
|
+
An audio driver was also written as a separate gem:
|
21
|
+
|
22
|
+
https://rubygems.org/gems/hallon-openal
|
23
|
+
|
24
|
+
__Added__
|
25
|
+
|
26
|
+
- Linkable#to_str, all linkable objects can now easily be converted to a spotify URI [132981a9]
|
27
|
+
- AudioQueue#clear/#synchronize/#new_cond (formerly Queue) [62bf4622, c2b14481, bb65cf28]
|
28
|
+
- AudioQueue#format/format= [27084a3a]
|
29
|
+
|
30
|
+
__Changed__
|
31
|
+
|
32
|
+
- Rewritten Player API (now deals in audio drivers) [53cfac21]
|
33
|
+
- Rewritten Enumerator system (Playlist#tracks, Search#albums et al) [676f7d1e]
|
34
|
+
- Search#{tracks,albums,artists}_total removed in favor of Search#{tracks,albums,artists}.total [d5c2e7aa]
|
35
|
+
- Image#== and Link#== [8a1e4a33]
|
36
|
+
- Player#load now accepts a spotify uri [710baf34]
|
37
|
+
- Renamed Queue to AudioQueue [c2b14481]
|
38
|
+
- Error.mabe_raise no longer ignores :is_loading, and now takes an :ignores option [53ad65c8]
|
39
|
+
|
40
|
+
__Fixed__
|
41
|
+
|
42
|
+
- Enumerators now check size before each iteration [4ec24969]
|
43
|
+
- Playlist#update_subscribers now returns the Playlist [86120836]
|
44
|
+
|
4
45
|
[v0.12.0][]
|
5
46
|
------------------
|
6
47
|
|
@@ -217,3 +258,5 @@ easier to handle.
|
|
217
258
|
[v0.10.1]: https://github.com/Burgestrand/Hallon/compare/v0.9.1...v0.10.1
|
218
259
|
[v0.11.0]: https://github.com/Burgestrand/Hallon/compare/v0.10.1...v0.11.0
|
219
260
|
[v0.12.0]: https://github.com/Burgestrand/Hallon/compare/v0.11.0...v0.12.0
|
261
|
+
[v0.13.0]: https://github.com/Burgestrand/Hallon/compare/v0.12.0...v0.13.0
|
262
|
+
[HEAD]: https://github.com/Burgestrand/Hallon/compare/v0.12.0...HEAD
|
data/Gemfile
CHANGED
data/README.markdown
CHANGED
@@ -1,9 +1,7 @@
|
|
1
1
|
[What is Hallon?][] [![Build Status][]](http://travis-ci.org/Burgestrand/Hallon)
|
2
|
-
|
2
|
+
===================
|
3
3
|
|
4
|
-
|
5
|
-
|
6
|
-
Hallon is Swedish for “[Raspberry][]”, and has been written to satisfy my needs for API simplicity. Hallon is written on top of [Spotify for Ruby][], but with the goal of making the experience of using `libspotify` from Ruby much more enjoyable.
|
4
|
+
Hallon — which is Swedish for “[Raspberry][]” — is a ruby gem for interacting with the official Spotify C API. It is written on top of [Spotify for Ruby][], with the goal of making the experience of using `libspotify` as enjoyable as it can be.
|
7
5
|
|
8
6
|
Hallon would not have been possible if not for these people:
|
9
7
|
|
@@ -16,13 +14,42 @@ Also, these people are worthy of mention simply for their contribution:
|
|
16
14
|
- Jesper Särnesjö, unknowingly providing me a starting point with [Greenstripes][]
|
17
15
|
- Emil “@mrevilme” Palm, for his patience in helping me debug Hallon deadlock issues
|
18
16
|
|
19
|
-
Code samples can be found under `examples/` directory.
|
17
|
+
Code samples can be found under the `examples/` directory. An explanation on how to run them can be found on the [Hallon wiki on GitHub](https://github.com/Burgestrand/Hallon/wiki).
|
18
|
+
|
19
|
+
Installation
|
20
|
+
------------
|
21
|
+
|
22
|
+
gem install hallon
|
23
|
+
|
24
|
+
If you want to play audio you’ll need to install an audio driver. As of current writing there is only one driver in existence. You can install it with:
|
25
|
+
|
26
|
+
gem install hallon-openal
|
27
|
+
|
28
|
+
For more information about audio support in Hallon, see the section "Audio support" below.
|
29
|
+
|
30
|
+
Audio support
|
31
|
+
-------------
|
32
|
+
Hallon supports streaming audio from Spotify via [Hallon::Player][]. When you create the player you give it your current session and an audio driver, which the player will then use for audio playback.
|
33
|
+
|
34
|
+
```ruby
|
35
|
+
player = Hallon::Player.new(session, Hallon::OpenAL)
|
36
|
+
player.play(loaded_track)
|
37
|
+
```
|
38
|
+
|
39
|
+
Available drivers are:
|
40
|
+
|
41
|
+
- [Hallon::OpenAL](https://rubygems.org/gems/hallon-openal)
|
42
|
+
|
43
|
+
gem install hallon-openal
|
44
|
+
|
45
|
+
For information on how to write your own audio driver, see [Hallon::ExampleAudioDriver].
|
20
46
|
|
21
47
|
You have any questions?
|
22
48
|
-----------------------
|
23
|
-
|
49
|
+
I can be reached at my [email (found on GitHub profile)](http://github.com/Burgestrand) or [@burgestrand on twitter](http://twitter.com/Burgestrand). I’d be extremely happy to discuss Hallon with
|
50
|
+
you if you have any feedback or thoughts.
|
24
51
|
|
25
|
-
|
52
|
+
For issues and feature requests, please use use [Hallons issue tracker](http://github.com/Burgestrand/Hallon/issues).
|
26
53
|
|
27
54
|
This is awesome! I want to help!
|
28
55
|
--------------------------------
|
@@ -34,20 +61,20 @@ Sweet! You contribute in more than one way!
|
|
34
61
|
### [Send me feedback and requests](http://github.com/Burgestrand/Hallon/issues)
|
35
62
|
Really, I ❤ feedback! Suggestions on how to improve the API, tell me what is delicious about Hallon, tell me what is yucky about Hallon… anything! All feedback is useful in one way or another.
|
36
63
|
|
37
|
-
Finally, here
|
38
|
-
|
64
|
+
Finally, here are some important notes
|
65
|
+
--------------------------------------
|
39
66
|
|
40
67
|
### Hallon is unstable
|
41
68
|
The API is unstable, my code is likely unstable. Everything should be considered unstable!
|
42
69
|
|
43
70
|
### Hallon only supports one session per process
|
44
|
-
You can only keep one session with Spotify alive at a time
|
71
|
+
You can only keep one session with Spotify alive at a time within the same process, due to a limitation of `libspotify`.
|
45
72
|
|
46
73
|
### You still have to worry about threads
|
47
74
|
I have been doing my best at hiding the complexity in `libspotify`, but it’s still a work in progress. Despite my efforts, you’ll need to be familiar with concurrent programming to use Hallon properly.
|
48
75
|
|
49
76
|
### When forking, you need to be extra careful
|
50
|
-
If you fork, you need to instantiate the session
|
77
|
+
If you fork, you need to instantiate the session within the process you plan to use Hallon in. You want to use Hallon in the parent? Create the session in the parent. You want to use it in the child? Create the session in the child! This is a limitation of libspotify itself.
|
51
78
|
|
52
79
|
Versioning policy
|
53
80
|
-----------------
|
@@ -66,3 +93,6 @@ Hallon is licensed under a 2-clause (Simplified) BSD license. More information c
|
|
66
93
|
[Greenstripes]: http://github.com/sarnesjo/greenstripes
|
67
94
|
[What is Hallon?]: http://burgestrand.se/articles/hallon-delicious-ruby-bindings-to-libspotify.html
|
68
95
|
[Build Status]: https://secure.travis-ci.org/Burgestrand/Hallon.png
|
96
|
+
|
97
|
+
[Hallon::Player]: http://rubydoc.info/github/Burgestrand/Hallon/Hallon/Player
|
98
|
+
[Hallon::ExampleAudioDriver]: http://rubydoc.info/github/Burgestrand/Hallon/Hallon/ExampleAudioDriver
|
data/Rakefile
CHANGED
@@ -110,6 +110,18 @@ task 'spotify:coverage' do
|
|
110
110
|
[method, "#{method}!"]
|
111
111
|
end
|
112
112
|
|
113
|
+
# Hallon::Enumerator
|
114
|
+
no_receiver[:size] = proc do |recv, meth, (_, name)|
|
115
|
+
name.value if name.respond_to?(:value)
|
116
|
+
end
|
117
|
+
|
118
|
+
# Hallon::Enumerator
|
119
|
+
no_receiver[:item] = proc do |recv, meth, (_, name)|
|
120
|
+
next unless name.respond_to?(:value)
|
121
|
+
method = name.value.to_s
|
122
|
+
[method.delete("!"), method]
|
123
|
+
end
|
124
|
+
|
113
125
|
fails = {}
|
114
126
|
FileList['lib/**/*.rb'].each do |file|
|
115
127
|
begin
|
@@ -0,0 +1,55 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
require 'monitor'
|
3
|
+
|
4
|
+
begin
|
5
|
+
require 'coreaudio'
|
6
|
+
rescue LoadError
|
7
|
+
abort <<-ERROR
|
8
|
+
This example requires the ruby-coreaudio gem.
|
9
|
+
|
10
|
+
See: http://rubygems.org/gems/coreaudio
|
11
|
+
ERROR
|
12
|
+
end
|
13
|
+
|
14
|
+
puts <<-INFO
|
15
|
+
**************************************************************
|
16
|
+
|
17
|
+
Keep in mind, you’re now using the CoreAudio driver, part
|
18
|
+
of Hallon examples. This driver does not buffer data, so
|
19
|
+
even the slightest hickup in Ruby will make the playback
|
20
|
+
stutter. The reason is that this CoreAudio driver does not
|
21
|
+
buffer data internally.
|
22
|
+
|
23
|
+
**************************************************************
|
24
|
+
INFO
|
25
|
+
|
26
|
+
module Hallon
|
27
|
+
class CoreAudio
|
28
|
+
attr_reader :output
|
29
|
+
protected :output
|
30
|
+
|
31
|
+
def initialize(format)
|
32
|
+
@device = ::CoreAudio.default_output_device
|
33
|
+
@output = @device.output_buffer(format[:rate] * 3)
|
34
|
+
@format = format
|
35
|
+
end
|
36
|
+
|
37
|
+
attr_accessor :format
|
38
|
+
|
39
|
+
def stream
|
40
|
+
loop { output << yield }
|
41
|
+
end
|
42
|
+
|
43
|
+
def play
|
44
|
+
output.start
|
45
|
+
end
|
46
|
+
|
47
|
+
def stop
|
48
|
+
output.stop
|
49
|
+
end
|
50
|
+
|
51
|
+
def pause
|
52
|
+
output.stop
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
data/examples/playing_audio.rb
CHANGED
@@ -2,22 +2,20 @@
|
|
2
2
|
|
3
3
|
$LOAD_PATH.unshift(File.expand_path('../lib', File.dirname(__FILE__)))
|
4
4
|
|
5
|
+
require 'bundler/setup'
|
5
6
|
require 'hallon'
|
6
|
-
require_relative '../spec/support/config'
|
7
7
|
|
8
8
|
begin
|
9
|
-
require '
|
9
|
+
require 'hallon/openal'
|
10
10
|
rescue LoadError
|
11
|
-
|
12
|
-
This example requires the ruby-coreaudio gem.
|
13
|
-
|
14
|
-
See: http://rubygems.org/gems/coreaudio
|
15
|
-
ERROR
|
11
|
+
require_relative 'audio_driver'
|
16
12
|
end
|
17
13
|
|
14
|
+
require_relative '../spec/support/config'
|
15
|
+
|
18
16
|
# Utility
|
19
17
|
def say(string)
|
20
|
-
system('say', string)
|
18
|
+
# system('say', string)
|
21
19
|
end
|
22
20
|
|
23
21
|
def tell(string)
|
@@ -34,16 +32,7 @@ end
|
|
34
32
|
|
35
33
|
# Hallon set-up.
|
36
34
|
|
37
|
-
sample_rate = 44100 # 44100 samples / second
|
38
|
-
device = CoreAudio.default_output_device
|
39
|
-
output = device.output_buffer(sample_rate * 3)
|
40
|
-
audio_queue = Hallon::Queue.new(sample_rate)
|
41
|
-
|
42
35
|
session = Hallon::Session.initialize IO.read(ENV['HALLON_APPKEY']) do
|
43
|
-
on(:log_message) do |message|
|
44
|
-
puts "[LOG] #{message}"
|
45
|
-
end
|
46
|
-
|
47
36
|
on(:connection_error) do |error|
|
48
37
|
Hallon::Error.maybe_raise(error)
|
49
38
|
end
|
@@ -53,31 +42,8 @@ session = Hallon::Session.initialize IO.read(ENV['HALLON_APPKEY']) do
|
|
53
42
|
end
|
54
43
|
end
|
55
44
|
|
56
|
-
|
57
|
-
player = Hallon::Player.new(session)
|
58
|
-
on(:music_delivery) do |format, frames|
|
59
|
-
audio_queue.push(frames)
|
60
|
-
end
|
61
|
-
|
62
|
-
on(:start_playback) do
|
63
|
-
puts "(start playback)"
|
64
|
-
output.start
|
65
|
-
end
|
66
|
-
|
67
|
-
on(:stop_playback) do
|
68
|
-
puts "(stop playback)"
|
69
|
-
output.stop
|
70
|
-
end
|
71
|
-
|
72
|
-
on(:get_audio_buffer_stats) do
|
73
|
-
[audio_queue.size, 0]
|
74
|
-
end
|
75
|
-
|
76
|
-
on(:end_of_track) do
|
77
|
-
puts "End of track!"
|
78
|
-
end_of_track = true
|
79
|
-
end
|
80
|
-
end
|
45
|
+
driver = defined?(Hallon::OpenAL) ? Hallon::OpenAL : Hallon::CoreAudio
|
46
|
+
player = Hallon::Player.new(session, driver)
|
81
47
|
|
82
48
|
# Program flow.
|
83
49
|
|
@@ -89,7 +55,7 @@ search = loop do
|
|
89
55
|
|
90
56
|
tell "Searching for “#{search.query}”…"
|
91
57
|
session.wait_for do
|
92
|
-
search.loaded? or Hallon::Error.maybe_raise(search.status)
|
58
|
+
search.loaded? or Hallon::Error.maybe_raise(search.status, ignore: :is_loading)
|
93
59
|
end
|
94
60
|
|
95
61
|
if search.tracks.size.zero?
|
@@ -119,12 +85,6 @@ track = loop do
|
|
119
85
|
end
|
120
86
|
end
|
121
87
|
|
122
|
-
player.play(track)
|
123
|
-
|
124
88
|
tell "Alright! Playing “#{track.name}” by “#{track.artist.name}”."
|
125
|
-
|
126
|
-
until end_of_track
|
127
|
-
output << audio_queue.pop(sample_rate)
|
128
|
-
end
|
129
|
-
|
89
|
+
player.play!(track)
|
130
90
|
tell "Done! This was “#{track.name}” by “#{track.artist.name}”. Bye bye!"
|
data/hallon.gemspec
CHANGED
@@ -19,7 +19,7 @@ Gem::Specification.new do |gem|
|
|
19
19
|
|
20
20
|
gem.version = Hallon::VERSION
|
21
21
|
gem.platform = Gem::Platform::RUBY
|
22
|
-
gem.required_ruby_version = '
|
22
|
+
gem.required_ruby_version = '>= 1.9'
|
23
23
|
|
24
24
|
gem.add_dependency 'ref', '~> 1.0'
|
25
25
|
gem.add_dependency 'spotify', '~> 10.3.0'
|
data/lib/hallon.rb
CHANGED
@@ -9,8 +9,8 @@ require 'hallon/linkable'
|
|
9
9
|
require 'hallon/version'
|
10
10
|
require 'hallon/error'
|
11
11
|
require 'hallon/base'
|
12
|
-
require 'hallon/queue'
|
13
12
|
require 'hallon/enumerator'
|
13
|
+
require 'hallon/audio_queue'
|
14
14
|
|
15
15
|
require 'hallon/observable/album_browse'
|
16
16
|
require 'hallon/observable/artist_browse'
|
data/lib/hallon/album_browse.rb
CHANGED
@@ -7,6 +7,24 @@ module Hallon
|
|
7
7
|
# @see Album
|
8
8
|
# @see http://developer.spotify.com/en/libspotify/docs/group__albumbrowse.html
|
9
9
|
class AlbumBrowse < Base
|
10
|
+
# Enumerates through all copyright notices of an album browsing object.
|
11
|
+
class Copyrights < Enumerator
|
12
|
+
size :albumbrowse_num_copyrights
|
13
|
+
|
14
|
+
# @return [String, nil]
|
15
|
+
item :albumbrowse_copyright
|
16
|
+
end
|
17
|
+
|
18
|
+
# Enumerates through all tracks of an album browsing object.
|
19
|
+
class Tracks < Enumerator
|
20
|
+
size :albumbrowse_num_tracks
|
21
|
+
|
22
|
+
# @return [Track, nil]
|
23
|
+
item :albumbrowse_track! do |track|
|
24
|
+
Track.from(track)
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
10
28
|
extend Observable::AlbumBrowse
|
11
29
|
|
12
30
|
# Creates an AlbumBrowse instance from an Album or an Album pointer.
|
@@ -65,21 +83,14 @@ module Hallon
|
|
65
83
|
Rational(duration, 1000) if duration > 0
|
66
84
|
end
|
67
85
|
|
68
|
-
# @return [
|
86
|
+
# @return [Copyrights] enumerator of copyright notices.
|
69
87
|
def copyrights
|
70
|
-
|
71
|
-
Enumerator.new(size) do |i|
|
72
|
-
Spotify.albumbrowse_copyright(pointer, i)
|
73
|
-
end
|
88
|
+
Copyrights.new(self)
|
74
89
|
end
|
75
90
|
|
76
|
-
# @return [
|
91
|
+
# @return [Tracks] enumerator of tracks.
|
77
92
|
def tracks
|
78
|
-
|
79
|
-
Enumerator.new(size) do |i|
|
80
|
-
track = Spotify.albumbrowse_track!(pointer, i)
|
81
|
-
Track.new(track)
|
82
|
-
end
|
93
|
+
Tracks.new(self)
|
83
94
|
end
|
84
95
|
end
|
85
96
|
end
|
data/lib/hallon/artist_browse.rb
CHANGED
@@ -5,6 +5,56 @@ module Hallon
|
|
5
5
|
# @see Artist
|
6
6
|
# @see http://developer.spotify.com/en/libspotify/docs/group__artistbrowse.html
|
7
7
|
class ArtistBrowse < Base
|
8
|
+
# Enumerates through all portrait images of an artist browsing object.
|
9
|
+
class Portraits < Enumerator
|
10
|
+
size :artistbrowse_num_portraits
|
11
|
+
|
12
|
+
# @return [Image, nil]
|
13
|
+
item :artistbrowse_portrait do |portrait|
|
14
|
+
Image.new(portrait)
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
# Enumerates through all portrait links of an artist browsing object.
|
19
|
+
class PortraitLinks < Enumerator
|
20
|
+
size :artistbrowse_num_portraits
|
21
|
+
|
22
|
+
# @return [Link, nil]
|
23
|
+
item :link_create_from_artistbrowse_portrait! do |portrait|
|
24
|
+
Link.from(portrait)
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
# Enumerates through all tracks of an artist browsing object.
|
29
|
+
class Tracks < Enumerator
|
30
|
+
size :artistbrowse_num_tracks
|
31
|
+
|
32
|
+
# @return [Track, nil]
|
33
|
+
item :artistbrowse_track! do |track|
|
34
|
+
Track.from(track)
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
# Enumerates through all albums of an artist browsing object.
|
39
|
+
class Albums < Enumerator
|
40
|
+
size :artistbrowse_num_albums
|
41
|
+
|
42
|
+
# @return [Album, nil]
|
43
|
+
item :artistbrowse_album! do |album|
|
44
|
+
Album.from(album)
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
# Enumerates through all similar artists of an artist browsing object.
|
49
|
+
class SimilarArtists < Enumerator
|
50
|
+
size :artistbrowse_num_similar_artists
|
51
|
+
|
52
|
+
# @return [Artist, nil]
|
53
|
+
item :artistbrowse_similar_artist! do |artist|
|
54
|
+
Artist.from(artist)
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
8
58
|
extend Observable::ArtistBrowse
|
9
59
|
|
10
60
|
# @return [Array<Symbol>] artist browsing types for use in {#initialize}
|
@@ -63,48 +113,29 @@ module Hallon
|
|
63
113
|
Rational(duration, 1000) if duration > 0
|
64
114
|
end
|
65
115
|
|
66
|
-
#
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
id = Spotify.artistbrowse_portrait(pointer, i)
|
75
|
-
Image.new(id)
|
76
|
-
else
|
77
|
-
link = Spotify.link_create_from_artistbrowse_portrait!(pointer, i)
|
78
|
-
Link.new(link)
|
79
|
-
end
|
80
|
-
end
|
116
|
+
# @return [Portraits] artist portraits as {Image}s.
|
117
|
+
def portraits
|
118
|
+
Portraits.new(self)
|
119
|
+
end
|
120
|
+
|
121
|
+
# @return [PortraitImages] artist portraits as {Link}s.
|
122
|
+
def portrait_links
|
123
|
+
PortraitLinks.new(self)
|
81
124
|
end
|
82
125
|
|
83
|
-
# @return [
|
126
|
+
# @return [Tracks] artist authored tracks.
|
84
127
|
def tracks
|
85
|
-
|
86
|
-
Enumerator.new(size) do |i|
|
87
|
-
track = Spotify.artistbrowse_track!(pointer, i)
|
88
|
-
Track.new(track)
|
89
|
-
end
|
128
|
+
Tracks.new(self)
|
90
129
|
end
|
91
130
|
|
92
|
-
# @return [
|
131
|
+
# @return [Albums] artist authored albums.
|
93
132
|
def albums
|
94
|
-
|
95
|
-
Enumerator.new(size) do |i|
|
96
|
-
album = Spotify.artistbrowse_album!(pointer, i)
|
97
|
-
Album.new(album)
|
98
|
-
end
|
133
|
+
Albums.new(self)
|
99
134
|
end
|
100
135
|
|
101
|
-
# @return [
|
136
|
+
# @return [SimilarArtists] similar artists to this artist.
|
102
137
|
def similar_artists
|
103
|
-
|
104
|
-
Enumerator.new(size) do |i|
|
105
|
-
artist = Spotify.artistbrowse_similar_artist!(pointer, i)
|
106
|
-
Artist.new(artist)
|
107
|
-
end
|
138
|
+
SimilarArtists.new(self)
|
108
139
|
end
|
109
140
|
end
|
110
141
|
end
|