hallon 0.8.0 → 0.9.0
Sign up to get free protection for your applications and to get access to all the features.
- data/.travis.yml +2 -0
- data/CHANGELOG +43 -0
- data/Gemfile +2 -0
- data/README.markdown +21 -13
- data/Rakefile +84 -23
- data/dev/login.rb +16 -0
- data/examples/adding_tracks_to_playlist.rb +49 -0
- data/examples/logging_in.rb +1 -6
- data/examples/show_published_playlists_of_user.rb +9 -19
- data/hallon.gemspec +1 -1
- data/lib/hallon.rb +3 -2
- data/lib/hallon/album.rb +55 -41
- data/lib/hallon/album_browse.rb +41 -37
- data/lib/hallon/artist.rb +30 -21
- data/lib/hallon/artist_browse.rb +59 -41
- data/lib/hallon/base.rb +68 -5
- data/lib/hallon/enumerator.rb +1 -0
- data/lib/hallon/error.rb +3 -0
- data/lib/hallon/ext/spotify.rb +169 -36
- data/lib/hallon/image.rb +30 -44
- data/lib/hallon/link.rb +29 -43
- data/lib/hallon/linkable.rb +68 -20
- data/lib/hallon/observable.rb +0 -1
- data/lib/hallon/player.rb +21 -7
- data/lib/hallon/playlist.rb +291 -0
- data/lib/hallon/playlist_container.rb +27 -0
- data/lib/hallon/search.rb +52 -45
- data/lib/hallon/session.rb +129 -81
- data/lib/hallon/toplist.rb +37 -19
- data/lib/hallon/track.rb +68 -45
- data/lib/hallon/user.rb +69 -33
- data/lib/hallon/version.rb +1 -1
- data/spec/hallon/album_browse_spec.rb +15 -9
- data/spec/hallon/album_spec.rb +15 -15
- data/spec/hallon/artist_browse_spec.rb +28 -9
- data/spec/hallon/artist_spec.rb +30 -14
- data/spec/hallon/enumerator_spec.rb +0 -1
- data/spec/hallon/hallon_spec.rb +20 -1
- data/spec/hallon/image_spec.rb +18 -41
- data/spec/hallon/link_spec.rb +10 -12
- data/spec/hallon/linkable_spec.rb +37 -18
- data/spec/hallon/player_spec.rb +8 -0
- data/spec/hallon/playlist_container_spec.rb +75 -0
- data/spec/hallon/playlist_spec.rb +204 -0
- data/spec/hallon/search_spec.rb +19 -16
- data/spec/hallon/session_spec.rb +61 -29
- data/spec/hallon/spotify_spec.rb +30 -0
- data/spec/hallon/toplist_spec.rb +22 -14
- data/spec/hallon/track_spec.rb +62 -21
- data/spec/hallon/user_spec.rb +47 -36
- data/spec/mockspotify.rb +35 -10
- data/spec/mockspotify/mockspotify_spec.rb +22 -0
- data/spec/spec_helper.rb +7 -3
- data/spec/support/common_objects.rb +91 -16
- data/spec/support/shared_for_linkable_objects.rb +39 -0
- metadata +30 -20
- data/Termfile +0 -7
- data/lib/hallon/synchronizable.rb +0 -32
- data/spec/hallon/synchronizable_spec.rb +0 -19
data/.travis.yml
CHANGED
data/CHANGELOG
CHANGED
@@ -1,6 +1,49 @@
|
|
1
1
|
Hallon’s Changelog
|
2
2
|
==================
|
3
3
|
|
4
|
+
v0.9.0
|
5
|
+
------------------
|
6
|
+
- Upgraded to libspotify *v10*
|
7
|
+
- Improve documentation consistency
|
8
|
+
- Link.new now raises an error if there’s no session
|
9
|
+
- Minimal PlaylistContainer support (more to come next version)
|
10
|
+
|
11
|
+
[ Added ]
|
12
|
+
- Playlist subsystem support
|
13
|
+
- Toplist#request_duration
|
14
|
+
- AlbumBrowse#request_duration
|
15
|
+
- ArtistBrowse#request_duration
|
16
|
+
- ArtistBrowse.types
|
17
|
+
- Player#volume_normalization(?|=)
|
18
|
+
- Session.new accepting device_id/tracefile options
|
19
|
+
- Session#login!/relogin!/logout! convenience methods
|
20
|
+
- Session#starred: starred playlist for currently logged in user
|
21
|
+
- Session#inbox: inbox for currently logged in user
|
22
|
+
- Session.instance?
|
23
|
+
- Image.new(image_id_in_hex) support
|
24
|
+
- Link#to_uri
|
25
|
+
- User.new(canonical_username)
|
26
|
+
- User#post: posting tracks to other users’ inboxes
|
27
|
+
- User#starred: starred playlist of a given user
|
28
|
+
- Track#placeholder?
|
29
|
+
- Track#offline_status
|
30
|
+
- Track#unwrap
|
31
|
+
- type parameter to Artist#browse
|
32
|
+
|
33
|
+
[ Fixed ]
|
34
|
+
- Moved from using FFI::Pointers to Spotify::Pointers
|
35
|
+
- Spotify::Pointer garbage collection
|
36
|
+
- Link#valid? using exceptions for flow control
|
37
|
+
- Session#connection_rules= now raises an error when given invalid rule
|
38
|
+
- Search.radio now raises an error when given invalid genres
|
39
|
+
|
40
|
+
[ Changed ]
|
41
|
+
- Playlist::Track#seen= removed in favor of Playlist#seen(index, yesno)
|
42
|
+
- Object#error -> Object#status (AlbumBrowse, ArtistBrowse, Search, Toplist, User)
|
43
|
+
- Album#year renamed to Album#release_year
|
44
|
+
- Linkable.from_link/to_link and resulting #from_link are now private
|
45
|
+
|
46
|
+
|
4
47
|
v0.8.0
|
5
48
|
------------------
|
6
49
|
[ Added ]
|
data/Gemfile
CHANGED
data/README.markdown
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
[What is Hallon?][] [![Build Status][]](http://travis-ci.org/Burgestrand/Hallon)
|
1
|
+
[What is Hallon?][] [![Build Status][]](http://travis-ci.org/Burgestrand/Hallon)
|
2
2
|
===============
|
3
3
|
|
4
4
|
We rubyists have this awesome [spotify gem][] allowing us to use [libspotify][] from within Ruby, but it has a significant drawback: the `libspotify` API is very hard to use. Now, we can’t have that, so what do we do? We make Hallon!
|
@@ -8,12 +8,22 @@ Hallon is Swedish for “Raspberry”, and has been written to satisfy my needs
|
|
8
8
|
Hallon would not have been possible if not for these people:
|
9
9
|
|
10
10
|
- Per Reimers, cracking synchronization bugs with me in the deep night (4 AM) and correcting me when I didn’t know better
|
11
|
-
- [Spotify]
|
12
|
-
- [Linus Oleander]
|
13
|
-
|
11
|
+
- [Spotify][], providing a service worth attention (and my money!)
|
12
|
+
- [Linus Oleander][], spawning the need for Hallon by having me in the [radiofy.se](http://radiofy.se) project
|
13
|
+
|
14
|
+
Also, these people are worthy of mention simply for their contribution:
|
15
|
+
|
16
|
+
- [Jesper Särnesjö][], unknowingly providing me a starting point with [Greenstripes][]
|
17
|
+
- Emil “@mrevilme” Palm, for his patience in helping me debug Hallon deadlock issues
|
14
18
|
|
15
19
|
Code samples can be found under `examples/` directory.
|
16
20
|
|
21
|
+
You have any questions?
|
22
|
+
-----------------------
|
23
|
+
If you need to discuss issues or feature requests you can use [Hallons issue tracker](http://github.com/Burgestrand/Hallon/issues). For *anything* else you have to say or ask I can also be reached via [email (found on GitHub profile)](http://github.com/Burgestrand) or [@burgestrand on twitter](http://twitter.com/Burgestrand).
|
24
|
+
|
25
|
+
In fact, you can contact me via email or twitter even if it’s about features or issues. I’ll probably put them in the issue tracker myself after the discussion ;)
|
26
|
+
|
17
27
|
This is awesome! I want to help!
|
18
28
|
--------------------------------
|
19
29
|
Sweet! You contribute in more than one way!
|
@@ -24,15 +34,8 @@ Sweet! You contribute in more than one way!
|
|
24
34
|
### [Send me feedback and requests](http://github.com/Burgestrand/Hallon/issues)
|
25
35
|
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.
|
26
36
|
|
27
|
-
|
28
|
-
|
29
|
-
If you need to discuss issues or feature requests you can use [Hallons issue tracker](http://github.com/Burgestrand/Hallon/issues). For *anything* else you have to say or ask I can also be reached via [email (found on GitHub profile)](http://github.com/Burgestrand) or [@burgestrand on twitter](http://twitter.com/Burgestrand).
|
30
|
-
|
31
|
-
In fact, you can contact me via email or twitter even if it’s about features or issues. I’ll probably put them in the issue tracker myself after the discussion ;)
|
32
|
-
|
33
|
-
What’s the catch?
|
34
|
-
-----------------
|
35
|
-
There are several!
|
37
|
+
Finally, here’s some important notes
|
38
|
+
------------------------------------
|
36
39
|
|
37
40
|
### Hallon is unstable
|
38
41
|
The API is unstable, my code is likely unstable. Everything should be considered unstable!
|
@@ -43,6 +46,9 @@ You can only keep one session with Spotify alive at a time in the same process,
|
|
43
46
|
### You still have to worry about threads
|
44
47
|
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.
|
45
48
|
|
49
|
+
### When forking, you need to be extra careful
|
50
|
+
If you fork, you need to instantiate the session in 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
|
+
|
46
52
|
Versioning policy
|
47
53
|
-----------------
|
48
54
|
Hallon uses [semantic versioning](http://semver.org) as of v0.0.0. As long
|
@@ -57,5 +63,7 @@ Hallon is licensed under a 2-clause (Simplified) BSD license. More information c
|
|
57
63
|
[libspotify]: http://developer.spotify.com/en/libspotify/overview/
|
58
64
|
[Greenstripes]: http://github.com/sarnesjo/greenstripes
|
59
65
|
[Jesper Särnesjö]: http://jesper.sarnesjo.org/
|
66
|
+
[Linus Oleander]: https://github.com/oleander
|
67
|
+
[Spotify]: http://spotify.com/
|
60
68
|
[What is Hallon?]: http://burgestrand.se/articles/hallon-delicious-ruby-bindings-to-libspotify.html
|
61
69
|
[Build Status]: https://secure.travis-ci.org/Burgestrand/Hallon.png
|
data/Rakefile
CHANGED
@@ -9,12 +9,12 @@ YARD::Rake::YardocTask.new
|
|
9
9
|
|
10
10
|
require 'rspec/core/rake_task'
|
11
11
|
RSpec::Core::RakeTask.new('spec') do |task|
|
12
|
-
task.skip_bundler = true
|
13
12
|
task.ruby_opts = '-W2'
|
14
13
|
end
|
15
14
|
|
16
15
|
desc "Run the full test suite and generate a coverage report"
|
17
16
|
task 'spec:cov' => ['clean', 'spec'] do
|
17
|
+
require 'bundler/setup'
|
18
18
|
require 'cover_me'
|
19
19
|
require './spec/support/cover_me'
|
20
20
|
|
@@ -24,6 +24,8 @@ end
|
|
24
24
|
|
25
25
|
desc "Process the Hallon codebase, finding out which Spotify methods are being used"
|
26
26
|
task 'spotify:coverage' do
|
27
|
+
require 'bundler/setup'
|
28
|
+
|
27
29
|
require 'set'
|
28
30
|
require 'spotify'
|
29
31
|
|
@@ -34,18 +36,39 @@ task 'spotify:coverage' do
|
|
34
36
|
abort
|
35
37
|
end
|
36
38
|
|
39
|
+
# Wrapped functions return pointers that are auto-GC’d by Ruby,
|
40
|
+
# so we ignore add_ref and release for these methods; but since
|
41
|
+
# we don’t know their type by mere name, we must resort to this
|
42
|
+
# hack to do it automatically (because we can).
|
43
|
+
class << Spotify
|
44
|
+
def lookup_return_value(name)
|
45
|
+
@function_to_return_type[name.to_s]
|
46
|
+
end
|
47
|
+
|
48
|
+
def define_singleton_method(name, &block)
|
49
|
+
return_type = block.binding.eval("return_type")
|
50
|
+
@function_to_return_type ||= {}
|
51
|
+
@function_to_return_type[name.to_s] = return_type
|
52
|
+
|
53
|
+
super
|
54
|
+
end
|
55
|
+
end
|
56
|
+
require 'hallon/ext/spotify'
|
57
|
+
|
37
58
|
methods = Spotify.methods(false).map(&:to_s)
|
59
|
+
auto_gc = Set.new(methods.grep(/!\z/))
|
38
60
|
covered = Set.new(methods)
|
61
|
+
warning = []
|
39
62
|
ignored = [
|
40
63
|
'session_release', # segfaults on libspotify <= 9
|
41
64
|
'session_userdata', # wont support this
|
42
65
|
'link_as_track', # using link_as_track_and_offset instead
|
43
|
-
'
|
44
|
-
'
|
45
|
-
'
|
46
|
-
'
|
47
|
-
'
|
48
|
-
'
|
66
|
+
'link_as_track!', # using link_as_track_and_offset! instead
|
67
|
+
'wrap_function', # not a spotify function
|
68
|
+
'lookup_return_value', # custom method
|
69
|
+
'define_singleton_method', # overloaded by us
|
70
|
+
'image_remove_load_callback', # cleared when Image is GCd
|
71
|
+
'playlist_remove_callbacks', # cleared when Playlist is GCd
|
49
72
|
]
|
50
73
|
|
51
74
|
covered -= ignored
|
@@ -56,28 +79,43 @@ task 'spotify:coverage' do
|
|
56
79
|
handlers = Hash.new(Hash.new(silencer))
|
57
80
|
|
58
81
|
# Direct calls
|
59
|
-
handlers[Sexp.new(:const, :Spotify)] = Hash.new(proc
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
82
|
+
handlers[Sexp.new(:const, :Spotify)] = Hash.new(proc do |_, meth, _|
|
83
|
+
if auto_gc.include?("#{meth}!")
|
84
|
+
warning << meth
|
85
|
+
end
|
86
|
+
|
87
|
+
result = [meth]
|
88
|
+
|
89
|
+
# if it’s auto-GC’d, we can also account for _release and _add_ref
|
90
|
+
if meth =~ /(.+)!\z/
|
91
|
+
return_type = Spotify.lookup_return_value(meth)
|
92
|
+
|
93
|
+
result << $1
|
94
|
+
result << "#{return_type}_release"
|
95
|
+
result << "#{return_type}_add_ref"
|
96
|
+
end
|
97
|
+
|
98
|
+
result
|
99
|
+
end)
|
68
100
|
|
69
101
|
# DSL Methods
|
70
102
|
no_receiver = handlers[nil] = Hash.new(silencer)
|
71
103
|
no_receiver[:from_link] = no_receiver[:to_link] = proc do |recv, meth, (_, name)|
|
72
104
|
prefix = meth == :to_link ? "link_create" : "link"
|
73
|
-
"%s_%s" % [prefix, name.value]
|
105
|
+
method = "%s_%s" % [prefix, name.value]
|
106
|
+
[method, "#{method}!"]
|
74
107
|
end
|
75
108
|
|
109
|
+
fails = {}
|
76
110
|
FileList['lib/**/*.rb'].each do |file|
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
111
|
+
begin
|
112
|
+
ast = RubyParser.new.parse File.read(file)
|
113
|
+
ast.each_of_type(:call) do |_, recv, meth, args, *rest|
|
114
|
+
name = handlers[recv][meth].call(recv, meth, args)
|
115
|
+
covered.subtract Array(name).map(&:to_s)
|
116
|
+
end
|
117
|
+
rescue => e
|
118
|
+
fails[file] = e.message.strip + " (#{e.class.name})"
|
81
119
|
end
|
82
120
|
end
|
83
121
|
|
@@ -91,15 +129,38 @@ task 'spotify:coverage' do
|
|
91
129
|
|
92
130
|
puts "Ignored:"
|
93
131
|
ignored.each_slice(3) do |slice|
|
94
|
-
puts "
|
132
|
+
puts " #{slice.join(', ')}"
|
95
133
|
end
|
96
134
|
puts
|
97
135
|
|
136
|
+
unless fails.empty?
|
137
|
+
puts "Failures:"
|
138
|
+
fails.each_pair do |file, fail|
|
139
|
+
puts " #{file}: #{fail}"
|
140
|
+
end
|
141
|
+
puts
|
142
|
+
end
|
143
|
+
|
144
|
+
unless warning.empty?
|
145
|
+
puts "Warnings (use auto-gc methods instead!):"
|
146
|
+
warning.each do |method|
|
147
|
+
puts " #{method}"
|
148
|
+
end
|
149
|
+
puts
|
150
|
+
end
|
151
|
+
|
98
152
|
puts "Coverage: %.02f%%" % (100 * (1 - covered.size.fdiv(methods.size)))
|
99
153
|
end
|
100
154
|
|
155
|
+
desc "Download mockspotify submodule"
|
156
|
+
task 'mock:fetch' do
|
157
|
+
unless File.exists?('./spec/mockspotify/libmockspotify/src/libmockspotify.h')
|
158
|
+
sh 'git submodule update --init'
|
159
|
+
end
|
160
|
+
end
|
161
|
+
|
101
162
|
desc "Compile mockspotify"
|
102
|
-
task 'mock:compile' do
|
163
|
+
task 'mock:compile' => 'mock:fetch' do
|
103
164
|
Dir.chdir 'spec/mockspotify' do
|
104
165
|
sh 'ruby extconf.rb'
|
105
166
|
sh 'make'
|
data/dev/login.rb
ADDED
@@ -0,0 +1,16 @@
|
|
1
|
+
$LOAD_PATH.unshift File.expand_path('../../lib', __FILE__)
|
2
|
+
require File.expand_path('../../spec/support/config', __FILE__)
|
3
|
+
|
4
|
+
require 'bundler/setup'
|
5
|
+
require 'hallon'
|
6
|
+
require 'pry'
|
7
|
+
|
8
|
+
session = Hallon::Session.initialize IO.read(ENV['HALLON_APPKEY']) do
|
9
|
+
on(:log_message) do |message|
|
10
|
+
puts "[LOG] #{message}"
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
session.login! ENV['HALLON_USERNAME'], ENV['HALLON_PASSWORD']
|
15
|
+
|
16
|
+
binding.pry
|
@@ -0,0 +1,49 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
require 'hallon'
|
3
|
+
require './spec/support/config'
|
4
|
+
|
5
|
+
##
|
6
|
+
# Configuration
|
7
|
+
#
|
8
|
+
# uri to the playlist you wish to add tracks to
|
9
|
+
playlist_uri = "spotify:user:burgestrand:playlist:07AX9IY9Hqmj1RqltcG0fi"
|
10
|
+
|
11
|
+
# array of track uris you wish to add to the playlist
|
12
|
+
track_uris = %w[spotify:track:6GHrP1i3vQo1e8VkEHRnvz spotify:track:2t7u74OJXHf0qQxXHpnb2R spotify:track:24q7a0Bo5MFLJUslg1lsS5]
|
13
|
+
|
14
|
+
# index to add the tracks to in the playlist
|
15
|
+
position = 0
|
16
|
+
|
17
|
+
session = Hallon::Session.initialize IO.read(ENV['HALLON_APPKEY']) do
|
18
|
+
on(:log_message) do |message|
|
19
|
+
puts "[LOG] #{message}"
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
session.login!(ENV['HALLON_USERNAME'], ENV['HALLON_PASSWORD'])
|
24
|
+
puts "Successfully logged in!"
|
25
|
+
|
26
|
+
# First, we load the playlist. This is necessary for libspotify
|
27
|
+
# to know if we have write access to it or not. Not doing it might
|
28
|
+
# end us up getting permission denied errors later.
|
29
|
+
puts "Loading playlist #{playlist_uri}"
|
30
|
+
playlist = Hallon::Playlist.new(playlist_uri)
|
31
|
+
session.wait_for { playlist.loaded? }
|
32
|
+
|
33
|
+
# Convert all track URIs to actual Tracks.
|
34
|
+
puts "Loading #{track_uris.length} tracks"
|
35
|
+
tracks = track_uris.map { |x| Hallon::Track.new(x) }
|
36
|
+
|
37
|
+
# … insert the tracks at the desired position into the playlist.
|
38
|
+
playlist.insert(position, tracks)
|
39
|
+
|
40
|
+
# finally, wait for the updates to the playlist to be acknowledged by the
|
41
|
+
# Spotify back-end. Once they have, we’ll see the tracks in our desktop
|
42
|
+
# client as well.
|
43
|
+
puts "Uploading playlist changes to Spotify back-end!"
|
44
|
+
|
45
|
+
state_changed = false
|
46
|
+
playlist.on(:playlist_state_changed) { state_changed = true }
|
47
|
+
session.wait_for { state_changed && ! playlist.pending? }
|
48
|
+
|
49
|
+
puts "We’re done!"
|
data/examples/logging_in.rb
CHANGED
@@ -8,11 +8,6 @@ session = Hallon::Session.initialize IO.read(ENV['HALLON_APPKEY']) do
|
|
8
8
|
end
|
9
9
|
end
|
10
10
|
|
11
|
-
session.login
|
12
|
-
|
13
|
-
session.wait_for(:logged_in) { |error| Hallon::Error.maybe_raise(error) }
|
14
|
-
session.wait_for(:connection_error) do |error|
|
15
|
-
session.logged_in? or Hallon::Error.maybe_raise(error)
|
16
|
-
end
|
11
|
+
session.login!(ENV['HALLON_USERNAME'], ENV['HALLON_PASSWORD'])
|
17
12
|
|
18
13
|
puts "Successfully logged in!"
|
@@ -39,12 +39,7 @@ session = Hallon::Session.initialize IO.read(ENV['HALLON_APPKEY']) do
|
|
39
39
|
end
|
40
40
|
end
|
41
41
|
|
42
|
-
session.login
|
43
|
-
|
44
|
-
session.wait_for(:logged_in) { |error| Hallon::Error.maybe_raise(error) }
|
45
|
-
session.wait_for(:connection_error) do |error|
|
46
|
-
session.logged_in? or Hallon::Error.maybe_raise(error)
|
47
|
-
end
|
42
|
+
session.login!(ENV['HALLON_USERNAME'], ENV['HALLON_PASSWORD'])
|
48
43
|
|
49
44
|
puts "Successfully logged in!"
|
50
45
|
|
@@ -55,7 +50,7 @@ while username = prompt("Enter a Spotify username: ")
|
|
55
50
|
username = nil if username.empty?
|
56
51
|
|
57
52
|
puts "Fetching container for #{username || "current user"}..."
|
58
|
-
container = Spotify::session_publishedcontainer_for_user_create(session.pointer, username)
|
53
|
+
container = Spotify::session_publishedcontainer_for_user_create!(session.pointer, username)
|
59
54
|
if container.null?
|
60
55
|
puts "Failed (unknown reason)."
|
61
56
|
next
|
@@ -67,26 +62,21 @@ while username = prompt("Enter a Spotify username: ")
|
|
67
62
|
puts "Listing #{num_playlists} playlists."
|
68
63
|
|
69
64
|
num_playlists.times do |i|
|
70
|
-
playlist = Spotify::playlistcontainer_playlist(container, i)
|
71
|
-
|
65
|
+
playlist = Spotify::playlistcontainer_playlist!(container, i)
|
66
|
+
playlist = Hallon::Playlist.new(playlist)
|
67
|
+
session.wait_for { playlist.loaded? }
|
72
68
|
|
73
69
|
puts
|
74
|
-
puts
|
70
|
+
puts playlist.name << ": "
|
75
71
|
|
76
|
-
num_tracks =
|
77
|
-
|
78
|
-
# Here we go back into Hallon API, passing the raw pointer
|
79
|
-
# to Hallon::Track.new; this means all of Hallon::Track API
|
80
|
-
# is supported on “track” here!
|
81
|
-
track = Hallon::Track.new(Spotify::playlist_track(playlist, j))
|
72
|
+
num_tracks = playlist.tracks.size
|
73
|
+
playlist.tracks.each_with_index do |track, i|
|
82
74
|
session.wait_for { track.loaded? }
|
83
75
|
|
84
|
-
puts "\t (#{
|
76
|
+
puts "\t (#{i+1}/#{num_tracks}) #{track.name}"
|
85
77
|
end
|
86
78
|
end
|
87
79
|
rescue Interrupt
|
88
80
|
# do nothing, continue with loop
|
89
|
-
ensure
|
90
|
-
Spotify::playlistcontainer_release(container) unless container.nil?
|
91
81
|
end
|
92
82
|
end
|
data/hallon.gemspec
CHANGED
@@ -21,7 +21,7 @@ Gem::Specification.new do |gem|
|
|
21
21
|
gem.platform = Gem::Platform::RUBY
|
22
22
|
gem.required_ruby_version = '~> 1.8'
|
23
23
|
|
24
|
-
gem.add_dependency 'spotify', '~>
|
24
|
+
gem.add_dependency 'spotify', '~> 10.1.0'
|
25
25
|
gem.add_development_dependency 'bundler', '~> 1.0'
|
26
26
|
gem.add_development_dependency 'rake', '~> 0.8'
|
27
27
|
gem.add_development_dependency 'rspec', '~> 2'
|
data/lib/hallon.rb
CHANGED
@@ -3,7 +3,6 @@ require 'spotify'
|
|
3
3
|
require 'hallon/ext/spotify'
|
4
4
|
require 'hallon/ext/ffi'
|
5
5
|
|
6
|
-
require 'hallon/synchronizable'
|
7
6
|
require 'hallon/observable'
|
8
7
|
require 'hallon/linkable'
|
9
8
|
|
@@ -11,6 +10,7 @@ require 'hallon/version'
|
|
11
10
|
require 'hallon/error'
|
12
11
|
require 'hallon/base'
|
13
12
|
require 'hallon/enumerator'
|
13
|
+
|
14
14
|
require 'hallon/session'
|
15
15
|
require 'hallon/link'
|
16
16
|
require 'hallon/user'
|
@@ -19,7 +19,8 @@ require 'hallon/track'
|
|
19
19
|
require 'hallon/album'
|
20
20
|
require 'hallon/artist'
|
21
21
|
require 'hallon/toplist'
|
22
|
-
|
22
|
+
require 'hallon/playlist'
|
23
|
+
require 'hallon/playlist_container'
|
23
24
|
require 'hallon/album_browse'
|
24
25
|
require 'hallon/artist_browse'
|
25
26
|
require 'hallon/player'
|