walkman 0.1.1 → 0.1.2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +2 -2
- data/bin/walkman +5 -0
- data/lib/walkman.rb +1 -28
- data/lib/walkman/cli.rb +7 -10
- data/lib/walkman/commands/controls.rb +1 -1
- data/lib/walkman/commands/playlist.rb +10 -1
- data/lib/walkman/commands/queueing.rb +17 -6
- data/lib/walkman/logger.rb +27 -0
- data/lib/walkman/player.rb +1 -4
- data/lib/walkman/playlist.rb +38 -51
- data/lib/walkman/services/base.rb +5 -5
- data/lib/walkman/services/rdio.rb +1 -0
- data/spec/fixtures/walkman.yml +13 -0
- data/spec/spec_helper.rb +8 -1
- data/spec/support/rspec.rb +5 -0
- data/spec/walkman/commands/controls_spec.rb +23 -0
- data/spec/walkman/commands/playlist_spec.rb +28 -0
- data/spec/walkman/commands/queueing_spec.rb +1 -0
- data/spec/walkman/config_spec.rb +78 -0
- data/spec/walkman/player_spec.rb +53 -7
- data/spec/walkman/playlist_spec.rb +37 -6
- data/spec/walkman_spec.rb +30 -0
- data/walkman.gemspec +2 -2
- metadata +38 -25
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 428f899c2b92b174d1e6693ee29932c5a9cd94e9
|
4
|
+
data.tar.gz: 5c352d5761efddeddfa5e685dfa4f081845473dc
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 43891034d99e8453e2dca48a3a839670038ddda1218862e709ab679c4613e15cb3c130e2b767334e07a3f1d1fb52472b776f81abe8effc83fdf37d5b1d67b7a6
|
7
|
+
data.tar.gz: ea21f3a6d49a991556b1dc0f1372a9000841ec7bd5ed3272bb859cac67f0803f8770b3e1bb9ec9056a7ce18f4b686bd93005f2655ec565740af3842a3f194aa9
|
data/README.md
CHANGED
@@ -29,7 +29,7 @@ with support for [Spotify](http://spotify.com) and local file playback via
|
|
29
29
|
3. Create a catalog (taste profile) to use as your base library and grab its `id` to use as `catalog_id`:
|
30
30
|
|
31
31
|
```
|
32
|
-
curl -F "api_key=<api_key>" -F "format=json" -F "type=general" -F "name=base_profile"
|
32
|
+
curl -F "api_key=<api_key>" -F "format=json" -F "type=general" -F "name=base_profile" "http://developer.echonest.com/api/v4/tasteprofile/create"
|
33
33
|
```
|
34
34
|
|
35
35
|
### Rdio
|
@@ -49,4 +49,4 @@ echonest:
|
|
49
49
|
catalog_id: CACABCD1234567890Z
|
50
50
|
rdio:
|
51
51
|
playback_token: GAlNi78J_____zlyYWs5ZG02N2pkaHlhcWsyOWJtYjkyN2xvY2FsaG9zdEbwl7EHvbylWSWFWYMZwfc=
|
52
|
-
```
|
52
|
+
```
|
data/bin/walkman
ADDED
data/lib/walkman.rb
CHANGED
@@ -1,6 +1,7 @@
|
|
1
1
|
require "echowrap"
|
2
2
|
|
3
3
|
require "walkman/config"
|
4
|
+
require "walkman/logger"
|
4
5
|
|
5
6
|
require "walkman/services/base"
|
6
7
|
require "walkman/services/rdio"
|
@@ -19,34 +20,6 @@ require "walkman/commands/queueing"
|
|
19
20
|
require "walkman/cli"
|
20
21
|
|
21
22
|
module Walkman
|
22
|
-
def self.logger
|
23
|
-
@@logger ||= ::Logger.new(STDOUT).tap do |l|
|
24
|
-
l.level = log_level(Walkman.config.log_level)
|
25
|
-
l.formatter = proc do |severity, _, _, message|
|
26
|
-
"[walkman](#{severity.downcase}): #{message}\n"
|
27
|
-
end
|
28
|
-
end
|
29
|
-
end
|
30
|
-
|
31
|
-
def self.log_level(log_level_string)
|
32
|
-
case log_level_string.to_s
|
33
|
-
when "unknown"
|
34
|
-
::Logger::UNKNOWN
|
35
|
-
when "fatal"
|
36
|
-
::Logger::FATAL
|
37
|
-
when "error"
|
38
|
-
::Logger::ERROR
|
39
|
-
when "warn"
|
40
|
-
::Logger::WARN
|
41
|
-
when "info"
|
42
|
-
::Logger::INFO
|
43
|
-
when "debug"
|
44
|
-
::Logger::DEBUG
|
45
|
-
else
|
46
|
-
raise "Unknown log level given #{log_level_string}"
|
47
|
-
end
|
48
|
-
end
|
49
|
-
|
50
23
|
def self.echowrap
|
51
24
|
@echowrap ||= Echowrap.configure do |config|
|
52
25
|
config.api_key = Walkman.config.echonest_api_key
|
data/lib/walkman/cli.rb
CHANGED
@@ -4,14 +4,13 @@ require "colorize"
|
|
4
4
|
|
5
5
|
module Walkman
|
6
6
|
class CLI < Thor
|
7
|
-
|
8
7
|
# server tasks
|
9
8
|
|
10
9
|
desc "start", "starts the walkman server"
|
11
10
|
option :daemon, type: :boolean, aliases: "-d"
|
12
11
|
def start
|
13
12
|
if options[:daemon]
|
14
|
-
Process.daemon
|
13
|
+
Process.daemon
|
15
14
|
else
|
16
15
|
puts "Starting walkman server"
|
17
16
|
puts "Run `walkman start -d` for daemon"
|
@@ -19,11 +18,9 @@ module Walkman
|
|
19
18
|
|
20
19
|
trap("INT") do
|
21
20
|
# calling this in a thread to get proper logging
|
22
|
-
|
21
|
+
Thread.new do
|
23
22
|
shutdown
|
24
|
-
end
|
25
|
-
|
26
|
-
thread.join
|
23
|
+
end.join
|
27
24
|
end
|
28
25
|
end
|
29
26
|
|
@@ -58,13 +55,13 @@ module Walkman
|
|
58
55
|
|
59
56
|
desc "next", "plays the next song in the current playlist"
|
60
57
|
def next(count = 1)
|
61
|
-
response = server.run_command(:next,
|
58
|
+
response = server.run_command(:next, count: count.to_i)
|
62
59
|
puts response unless response.empty?
|
63
60
|
end
|
64
61
|
|
65
62
|
desc "skip COUNT", "skips the given amount of songs"
|
66
63
|
def skip(count = 1)
|
67
|
-
response = server.run_command(:skip,
|
64
|
+
response = server.run_command(:skip, count: count.to_i)
|
68
65
|
puts response unless response.empty?
|
69
66
|
end
|
70
67
|
|
@@ -83,14 +80,14 @@ module Walkman
|
|
83
80
|
desc "play_artist ARTIST", "plays songs from the given artist"
|
84
81
|
def play_artist(*artist)
|
85
82
|
artist = artist.join(" ")
|
86
|
-
response = server.run_command(:artist,
|
83
|
+
response = server.run_command(:artist, artist: artist)
|
87
84
|
puts response unless response.empty?
|
88
85
|
end
|
89
86
|
|
90
87
|
desc "play_artist_radio ARTIST", "plays music like the given artist"
|
91
88
|
def play_artist_radio(*artist)
|
92
89
|
artist = artist.join(" ")
|
93
|
-
response = server.run_command(:artist_radio,
|
90
|
+
response = server.run_command(:artist_radio, artist: artist)
|
94
91
|
puts response unless response.empty?
|
95
92
|
end
|
96
93
|
|
@@ -6,12 +6,21 @@ module Walkman
|
|
6
6
|
playlist = Walkman.player.playlist
|
7
7
|
|
8
8
|
if current_song && playlist
|
9
|
-
playlist.favorite
|
9
|
+
playlist.feedback(:favorite, current_song)
|
10
10
|
"Awesome! I'll play more songs like this."
|
11
11
|
else
|
12
12
|
"No music is playing. Are you hearing things?"
|
13
13
|
end
|
14
14
|
end
|
15
|
+
|
16
|
+
def self.shuffle!
|
17
|
+
if playlist = Walkman.player.playlist
|
18
|
+
playlist.shuffle!
|
19
|
+
"Shaking things up a bit."
|
20
|
+
else
|
21
|
+
"No music is queued."
|
22
|
+
end
|
23
|
+
end
|
15
24
|
end
|
16
25
|
end
|
17
26
|
end
|
@@ -2,11 +2,9 @@ module Walkman
|
|
2
2
|
module Commands
|
3
3
|
module Queueing
|
4
4
|
def self.artist(artist)
|
5
|
-
playlist =
|
6
|
-
Walkman.player.playlist = playlist
|
5
|
+
playlist = self.queue("artist", artist: artist)
|
7
6
|
|
8
7
|
if playlist.size > 0
|
9
|
-
Walkman.player.next
|
10
8
|
output = ["♫".blue, "Playing songs by", artist.titleize.bold]
|
11
9
|
output.flatten.join(" ")
|
12
10
|
else
|
@@ -15,17 +13,30 @@ module Walkman
|
|
15
13
|
end
|
16
14
|
|
17
15
|
def self.artist_radio(artist)
|
18
|
-
playlist =
|
19
|
-
Walkman.player.playlist = playlist
|
16
|
+
playlist = self.queue("artist-radio", artist: artist)
|
20
17
|
|
21
18
|
if playlist.size > 0
|
22
|
-
Walkman.player.next
|
23
19
|
output = ["♫".blue, "Playing music like", artist.titleize.bold]
|
24
20
|
output.flatten.join(" ")
|
25
21
|
else
|
26
22
|
"Music like that artist couldn't be queued"
|
27
23
|
end
|
28
24
|
end
|
25
|
+
|
26
|
+
private
|
27
|
+
|
28
|
+
def self.queue(type, args = {})
|
29
|
+
args.merge!(type: type.to_s, auto_queue: true)
|
30
|
+
|
31
|
+
playlist = Walkman::Playlist.new(args)
|
32
|
+
Walkman.player.playlist = playlist
|
33
|
+
|
34
|
+
if playlist.size > 0
|
35
|
+
Walkman.player.next
|
36
|
+
end
|
37
|
+
|
38
|
+
playlist
|
39
|
+
end
|
29
40
|
end
|
30
41
|
end
|
31
42
|
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
module Walkman
|
2
|
+
def self.logger
|
3
|
+
@@logger ||= ::Logger.new(STDOUT).tap do |l|
|
4
|
+
l.level = log_level(Walkman.config.log_level)
|
5
|
+
l.formatter = proc do |severity, _, _, message|
|
6
|
+
"[walkman](#{severity.downcase}): #{message}\n"
|
7
|
+
end
|
8
|
+
end
|
9
|
+
end
|
10
|
+
|
11
|
+
def self.log_level(log_level_string)
|
12
|
+
case log_level_string.to_s
|
13
|
+
when "debug"
|
14
|
+
::Logger::DEBUG
|
15
|
+
when "info"
|
16
|
+
::Logger::INFO
|
17
|
+
when "warn"
|
18
|
+
::Logger::WARN
|
19
|
+
when "error"
|
20
|
+
::Logger::ERROR
|
21
|
+
when "fatal"
|
22
|
+
::Logger::FATAL
|
23
|
+
else
|
24
|
+
raise "Unknown log level given #{log_level_string}"
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
data/lib/walkman/player.rb
CHANGED
@@ -5,6 +5,7 @@ module Walkman
|
|
5
5
|
|
6
6
|
class Player
|
7
7
|
attr_accessor :current_song, :playing
|
8
|
+
attr_writer :playlist
|
8
9
|
|
9
10
|
SERVICES = [Walkman::Services::Rdio]
|
10
11
|
|
@@ -92,10 +93,6 @@ module Walkman
|
|
92
93
|
@playlist ||= Walkman::Playlist.new
|
93
94
|
end
|
94
95
|
|
95
|
-
def playlist=(playlist)
|
96
|
-
@playlist = playlist
|
97
|
-
end
|
98
|
-
|
99
96
|
private
|
100
97
|
|
101
98
|
def play_song(song)
|
data/lib/walkman/playlist.rb
CHANGED
@@ -1,6 +1,7 @@
|
|
1
1
|
module Walkman
|
2
2
|
class Playlist
|
3
3
|
attr_accessor :session_id
|
4
|
+
attr_reader :queue
|
4
5
|
|
5
6
|
def initialize(options = {})
|
6
7
|
songs = options.delete(:songs) || []
|
@@ -12,14 +13,11 @@ module Walkman
|
|
12
13
|
end
|
13
14
|
|
14
15
|
if @auto_queue && @session_id
|
15
|
-
auto_queue
|
16
|
+
auto_queue
|
17
|
+
self.next
|
16
18
|
end
|
17
19
|
end
|
18
20
|
|
19
|
-
def queue
|
20
|
-
@queue
|
21
|
-
end
|
22
|
-
|
23
21
|
def clear
|
24
22
|
@queue = []
|
25
23
|
end
|
@@ -29,7 +27,7 @@ module Walkman
|
|
29
27
|
end
|
30
28
|
alias_method :queued?, :include?
|
31
29
|
|
32
|
-
def shuffle
|
30
|
+
def shuffle!
|
33
31
|
@queue.shuffle!
|
34
32
|
end
|
35
33
|
|
@@ -51,7 +49,7 @@ module Walkman
|
|
51
49
|
song = songs.pop # the last song skipped
|
52
50
|
|
53
51
|
# skip and unplay songs so our echonest catalog/profile stays true
|
54
|
-
skip
|
52
|
+
feedback([:skip, :unplay], songs) unless songs.empty?
|
55
53
|
|
56
54
|
if @auto_queue && size <= 5
|
57
55
|
auto_queue(5) if @session_id
|
@@ -64,76 +62,65 @@ module Walkman
|
|
64
62
|
@queue.size
|
65
63
|
end
|
66
64
|
|
67
|
-
def
|
68
|
-
songs
|
69
|
-
|
70
|
-
songs.
|
71
|
-
|
72
|
-
end
|
73
|
-
end
|
74
|
-
|
75
|
-
def skip(songs)
|
76
|
-
songs = [songs].flatten # one or more
|
65
|
+
def feedback(types, songs)
|
66
|
+
songs = [songs].flatten # one or more
|
67
|
+
types = [types].flatten # one or more
|
68
|
+
song_ids = songs.map(&:echonest_song_id)
|
69
|
+
args = { session_id: @session_id }
|
77
70
|
|
78
|
-
|
79
|
-
|
71
|
+
if types.include?(:favorite)
|
72
|
+
args[:favorite_song] = song_ids
|
73
|
+
args[:favorite_artist] = songs.map(&:echonest_artist_id)
|
80
74
|
end
|
81
|
-
end
|
82
75
|
|
83
|
-
|
84
|
-
|
76
|
+
args[:unplay_song] = song_ids if types.include?(:unplay)
|
77
|
+
args[:skip_song] = song_ids if types.include?(:skip)
|
85
78
|
|
86
|
-
|
87
|
-
echonest_playlist_feedback({ favorite_song: song.echonest_song_id, favorite_artist: song.echonest_artist_id })
|
88
|
-
end
|
79
|
+
Walkman.echowrap.playlist_dynamic_feedback(args)
|
89
80
|
end
|
90
81
|
|
91
82
|
private
|
92
83
|
|
93
|
-
def echonest_playlist_create(
|
94
|
-
return nil unless
|
84
|
+
def echonest_playlist_create(args = {})
|
85
|
+
return nil unless args.keys.include?(:type)
|
95
86
|
|
96
|
-
|
97
|
-
|
98
|
-
|
87
|
+
args[:bucket] = ["id:rdio-US", "tracks"]
|
88
|
+
args[:seed_catalog] = Walkman.config.echonest_catalog_id
|
89
|
+
args[:session_catalog] = Walkman.config.echonest_catalog_id
|
99
90
|
|
100
|
-
if remote_playlist = Walkman.echowrap.playlist_dynamic_create(
|
91
|
+
if remote_playlist = Walkman.echowrap.playlist_dynamic_create(args)
|
101
92
|
remote_playlist
|
102
93
|
else
|
103
94
|
nil
|
104
95
|
end
|
105
96
|
end
|
106
97
|
|
107
|
-
def echonest_playlist_feedback(args = {})
|
108
|
-
args[:session_id] = @session_id
|
109
|
-
|
110
|
-
Walkman.echowrap.playlist_dynamic_feedback(args)
|
111
|
-
end
|
112
|
-
|
113
98
|
def auto_queue(count = 5)
|
114
99
|
return 0 unless @session_id
|
115
100
|
|
116
101
|
result = Walkman.echowrap.playlist_dynamic_next(session_id: @session_id, results: count)
|
117
|
-
songs =
|
102
|
+
songs = parse_remote_songs(result.songs)
|
103
|
+
add(songs)
|
104
|
+
end
|
118
105
|
|
119
|
-
|
106
|
+
def parse_remote_songs(remote_songs)
|
107
|
+
remote_songs.map do |song|
|
120
108
|
# find the first track with a rdio foreign key
|
121
109
|
track = song.tracks.find do |t|
|
122
110
|
t.foreign_id && t.foreign_id.split(":")[0] == "rdio-US"
|
123
111
|
end
|
124
112
|
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
songs.count
|
113
|
+
if track
|
114
|
+
Walkman::Song.new(artist: song.artist_name,
|
115
|
+
title: song.title,
|
116
|
+
source_type: "Walkman::Services::Rdio",
|
117
|
+
source_id: track.foreign_id.split(":").last,
|
118
|
+
echonest_artist_id: song.artist_id,
|
119
|
+
echonest_song_id: song.id)
|
120
|
+
else
|
121
|
+
nil
|
122
|
+
end
|
123
|
+
end.compact # prune any nil elements
|
137
124
|
end
|
138
125
|
end
|
139
126
|
end
|
@@ -2,23 +2,23 @@ module Walkman
|
|
2
2
|
module Services
|
3
3
|
class Base
|
4
4
|
def startup
|
5
|
-
raise
|
5
|
+
raise "Implement in Service"
|
6
6
|
end
|
7
7
|
|
8
8
|
def shutdown
|
9
|
-
raise
|
9
|
+
raise "Implement in Service"
|
10
10
|
end
|
11
11
|
|
12
12
|
def restart
|
13
|
-
raise
|
13
|
+
raise "Implement in Service"
|
14
14
|
end
|
15
15
|
|
16
16
|
def play(song)
|
17
|
-
raise
|
17
|
+
raise "Implement in Service"
|
18
18
|
end
|
19
19
|
|
20
20
|
def stop
|
21
|
-
raise
|
21
|
+
raise "Implement in Service"
|
22
22
|
end
|
23
23
|
end
|
24
24
|
end
|
data/spec/spec_helper.rb
CHANGED
@@ -7,4 +7,11 @@ require "walkman"
|
|
7
7
|
|
8
8
|
Dir[File.expand_path("../support/*.rb", __FILE__)].each { |f| require f }
|
9
9
|
|
10
|
-
Walkman.
|
10
|
+
Walkman.config.log_level = :info
|
11
|
+
|
12
|
+
before do
|
13
|
+
Walkman.echowrap.stub(:playlist_dynamic_create)
|
14
|
+
Walkman.echowrap.stub(:playlist_dynamic_feedback)
|
15
|
+
Walkman.echowrap.stub(:playlist_dynamic_next)
|
16
|
+
Command.stub(:run)
|
17
|
+
end
|
@@ -3,6 +3,10 @@ require "spec_helper"
|
|
3
3
|
describe Walkman::Commands::Controls do
|
4
4
|
let!(:player) { Walkman.player }
|
5
5
|
|
6
|
+
before do
|
7
|
+
Walkman.echowrap.stub(:playlist_dynamic_feedback)
|
8
|
+
end
|
9
|
+
|
6
10
|
describe ".play" do
|
7
11
|
it "calls play on the player" do
|
8
12
|
expect(player).to receive(:play)
|
@@ -22,5 +26,24 @@ describe Walkman::Commands::Controls do
|
|
22
26
|
expect(player).to receive(:next)
|
23
27
|
Walkman::Commands::Controls.next
|
24
28
|
end
|
29
|
+
|
30
|
+
it "updates the current song's skip count" do
|
31
|
+
song = create(:song)
|
32
|
+
player.current_song = song
|
33
|
+
player.playlist = create(:playlist)
|
34
|
+
|
35
|
+
expect(player.playlist).to receive(:feedback).with(:skip, song).once
|
36
|
+
|
37
|
+
Walkman::Commands::Controls.next
|
38
|
+
end
|
39
|
+
|
40
|
+
it "updates the skipped songs' skip count" do
|
41
|
+
songs = create_list(:song, 3)
|
42
|
+
player.playlist = create(:playlist, songs: songs)
|
43
|
+
|
44
|
+
expect(player.playlist).to receive(:feedback).with([:skip, :unplay], songs.take(2)).once
|
45
|
+
|
46
|
+
Walkman::Commands::Controls.skip(3)
|
47
|
+
end
|
25
48
|
end
|
26
49
|
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
require "spec_helper"
|
2
|
+
|
3
|
+
describe Walkman::Commands::Playlist do
|
4
|
+
let!(:player) { Walkman.player }
|
5
|
+
let!(:playlist) { Walkman::Playlist.new }
|
6
|
+
|
7
|
+
before do
|
8
|
+
Walkman.echowrap.stub(:playlist_dynamic_feedback)
|
9
|
+
end
|
10
|
+
|
11
|
+
describe ".like" do
|
12
|
+
it "updates the song's like count" do
|
13
|
+
player.playlist = playlist
|
14
|
+
song = create(:song)
|
15
|
+
player.current_song = song
|
16
|
+
|
17
|
+
expect(player.playlist).to receive(:feedback).with(:favorite, song)
|
18
|
+
|
19
|
+
expect(Walkman::Commands::Playlist.like).to eq("Awesome! I'll play more songs like this.")
|
20
|
+
end
|
21
|
+
|
22
|
+
it "returns a notification if there is not a current song" do
|
23
|
+
player.current_song = nil
|
24
|
+
|
25
|
+
expect(Walkman::Commands::Playlist.like).to eq("No music is playing. Are you hearing things?")
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
@@ -12,6 +12,7 @@ describe Walkman::Commands::Queueing do
|
|
12
12
|
|
13
13
|
Walkman.echowrap.stub(:playlist_dynamic_create) { playlist_dynamic_create }
|
14
14
|
Walkman.echowrap.stub(:playlist_dynamic_next) { playlist_dynamic_next }
|
15
|
+
Walkman.echowrap.stub(:playlist_dynamic_feedback)
|
15
16
|
end
|
16
17
|
|
17
18
|
describe ".artist" do
|
@@ -0,0 +1,78 @@
|
|
1
|
+
require "spec_helper"
|
2
|
+
|
3
|
+
describe Walkman::Config do
|
4
|
+
let!(:config) { Walkman::Config.new }
|
5
|
+
|
6
|
+
it "ensures only one Config object exists" do
|
7
|
+
config = Walkman.config
|
8
|
+
|
9
|
+
expect(config).to eq(Walkman.config)
|
10
|
+
end
|
11
|
+
|
12
|
+
describe "global configs" do
|
13
|
+
it "has a log level" do
|
14
|
+
expect(config.log_level).to eq("debug")
|
15
|
+
|
16
|
+
config.log_level = "info"
|
17
|
+
|
18
|
+
expect(config.log_level).to eq("info")
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
describe "server configs" do
|
23
|
+
it "has a server host" do
|
24
|
+
expect(config.server_host).to eq("localhost")
|
25
|
+
end
|
26
|
+
|
27
|
+
it "has a server port" do
|
28
|
+
expect(config.server_port).to eq(27001)
|
29
|
+
end
|
30
|
+
|
31
|
+
it "has a DRb URI" do
|
32
|
+
expect(config.drb_uri).to eq("druby://localhost:27001")
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
describe "echo nest configs" do
|
37
|
+
it "has a echo nest api key" do
|
38
|
+
expect(config.echonest_api_key).to be_nil
|
39
|
+
end
|
40
|
+
|
41
|
+
it "has a echo nest consumer key" do
|
42
|
+
expect(config.echonest_consumer_key).to be_nil
|
43
|
+
end
|
44
|
+
|
45
|
+
it "has a echo nest shared secret" do
|
46
|
+
expect(config.echonest_shared_secret).to be_nil
|
47
|
+
end
|
48
|
+
|
49
|
+
it "has a echo nest catalog id" do
|
50
|
+
expect(config.echonest_catalog_id).to be_nil
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
describe "rdio configs" do
|
55
|
+
it "has a rdio player url" do
|
56
|
+
expect(config.rdio_player_url).to eq("http://localhost:4567/rdio")
|
57
|
+
end
|
58
|
+
|
59
|
+
it "has a rdio playback token" do
|
60
|
+
expect(config.rdio_playback_token).to be_nil
|
61
|
+
end
|
62
|
+
|
63
|
+
it "has a rdio browser path" do
|
64
|
+
expect(config.rdio_browser_path).to eq('/Applications/Google\ Chrome.app/Contents/MacOS/Google\ Chrome --no-process-singleton-dialog')
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
it "can load config values from a given YAML file" do
|
69
|
+
config_file = File.join(File.dirname(__FILE__), "..", "fixtures", "walkman.yml")
|
70
|
+
config.load_file(config_file)
|
71
|
+
|
72
|
+
expect(config.echonest_api_key).to eq("ABC")
|
73
|
+
expect(config.echonest_consumer_key).to eq("DEF")
|
74
|
+
expect(config.echonest_shared_secret).to eq("GHI")
|
75
|
+
expect(config.echonest_catalog_id).to eq("JKL")
|
76
|
+
expect(config.rdio_playback_token).to eq("MNO")
|
77
|
+
end
|
78
|
+
end
|
data/spec/walkman/player_spec.rb
CHANGED
@@ -3,9 +3,22 @@ require "spec_helper"
|
|
3
3
|
describe Walkman::Player do
|
4
4
|
let!(:player) { Walkman.player }
|
5
5
|
|
6
|
-
|
7
|
-
|
6
|
+
before do
|
7
|
+
Walkman.echowrap.stub(:playlist_dynamic_feedback)
|
8
|
+
Command.stub(:run)
|
9
|
+
|
10
|
+
Walkman::Player::SERVICES.each do |service|
|
11
|
+
service.any_instance.stub(:startup)
|
12
|
+
service.any_instance.stub(:shutdown)
|
13
|
+
end
|
14
|
+
|
8
15
|
player.playlist = nil
|
16
|
+
player.current_song = nil
|
17
|
+
player.startup
|
18
|
+
end
|
19
|
+
|
20
|
+
after do
|
21
|
+
player.shutdown
|
9
22
|
end
|
10
23
|
|
11
24
|
it "responds to #playlist" do
|
@@ -21,12 +34,45 @@ describe Walkman::Player do
|
|
21
34
|
describe "#startup" do
|
22
35
|
it "starts up all music services" do
|
23
36
|
Walkman::Player::SERVICES.each do |service|
|
24
|
-
service.any_instance.
|
37
|
+
service.any_instance.unstub(:startup)
|
25
38
|
expect_any_instance_of(service).to receive(:startup)
|
26
39
|
end
|
27
40
|
|
28
41
|
player.startup
|
29
42
|
end
|
43
|
+
|
44
|
+
describe "play loop" do
|
45
|
+
it "calls #next if there is no current song" do
|
46
|
+
player.current_song = nil
|
47
|
+
|
48
|
+
expect(player).to receive(:next).at_least(1)
|
49
|
+
|
50
|
+
player.play
|
51
|
+
sleep 0.1
|
52
|
+
end
|
53
|
+
|
54
|
+
it "calls #stop if the last loop song is different than the current loop song" do
|
55
|
+
player.current_song = create(:song)
|
56
|
+
player.playlist = create(:playlist)
|
57
|
+
player.playlist.add(create(:song))
|
58
|
+
|
59
|
+
expect(player).to receive(:stop)
|
60
|
+
|
61
|
+
player.play
|
62
|
+
sleep 0.2
|
63
|
+
player.current_song = create(:song)
|
64
|
+
sleep 0.1
|
65
|
+
end
|
66
|
+
|
67
|
+
it "calls #play_song if the last loop song is nil" do
|
68
|
+
player.current_song = create(:song)
|
69
|
+
|
70
|
+
expect(player).to receive(:play_song)
|
71
|
+
|
72
|
+
player.play
|
73
|
+
sleep 0.1
|
74
|
+
end
|
75
|
+
end
|
30
76
|
end
|
31
77
|
|
32
78
|
describe "#shutdown" do
|
@@ -42,8 +88,6 @@ describe Walkman::Player do
|
|
42
88
|
|
43
89
|
describe "#play" do
|
44
90
|
it "plays a song from a specific music service" do
|
45
|
-
player.startup
|
46
|
-
|
47
91
|
Walkman::Player::SERVICES.each do |service|
|
48
92
|
service.any_instance.stub(:play)
|
49
93
|
player.current_song = create(:song, source_type: service.name)
|
@@ -51,19 +95,21 @@ describe Walkman::Player do
|
|
51
95
|
end
|
52
96
|
|
53
97
|
player.play
|
54
|
-
|
55
98
|
sleep 0.2 # have to give the play loop a chance to pick up the song
|
56
99
|
end
|
57
100
|
end
|
58
101
|
|
59
102
|
describe "#stop" do
|
60
103
|
it "stops all music services" do
|
104
|
+
player.instance_variable_set("@play_loop", nil)
|
105
|
+
|
61
106
|
Walkman::Player::SERVICES.each do |service|
|
62
107
|
service.any_instance.stub(:stop)
|
63
108
|
expect_any_instance_of(service).to receive(:stop)
|
64
109
|
end
|
65
110
|
|
66
111
|
player.stop
|
112
|
+
sleep 0.2 # have to give the play loop a chance to pick up the song
|
67
113
|
end
|
68
114
|
end
|
69
115
|
|
@@ -96,7 +142,7 @@ describe Walkman::Player do
|
|
96
142
|
player.next
|
97
143
|
|
98
144
|
expect(player.current_song).to be_nil
|
99
|
-
expect(player.playing).to
|
145
|
+
expect(player.playing).to eq(false)
|
100
146
|
end
|
101
147
|
end
|
102
148
|
end
|
@@ -4,6 +4,11 @@ describe Walkman::Playlist do
|
|
4
4
|
let(:playlist) { create(:playlist) }
|
5
5
|
let(:song) { create(:song) }
|
6
6
|
|
7
|
+
before do
|
8
|
+
Walkman.echowrap.stub(:playlist_dynamic_feedback)
|
9
|
+
playlist.session_id = "ABC123"
|
10
|
+
end
|
11
|
+
|
7
12
|
it "responds to #session_id" do
|
8
13
|
expect(playlist).to respond_to(:session_id)
|
9
14
|
end
|
@@ -39,13 +44,13 @@ describe Walkman::Playlist do
|
|
39
44
|
it "returns true if the given song is currently queued" do
|
40
45
|
playlist.add(song)
|
41
46
|
|
42
|
-
expect(playlist.include?(song)).to
|
43
|
-
expect(playlist.queued?(song)).to
|
47
|
+
expect(playlist.include?(song)).to eq(true)
|
48
|
+
expect(playlist.queued?(song)).to eq(true)
|
44
49
|
end
|
45
50
|
|
46
51
|
it "returns false if the given song is not currently queued" do
|
47
|
-
expect(playlist.include?(song)).to
|
48
|
-
expect(playlist.queued?(song)).to
|
52
|
+
expect(playlist.include?(song)).to eq(false)
|
53
|
+
expect(playlist.queued?(song)).to eq(false)
|
49
54
|
end
|
50
55
|
end
|
51
56
|
|
@@ -117,12 +122,12 @@ describe Walkman::Playlist do
|
|
117
122
|
end
|
118
123
|
end
|
119
124
|
|
120
|
-
describe "#shuffle" do
|
125
|
+
describe "#shuffle!" do
|
121
126
|
it "changes the order of songs in the queue" do
|
122
127
|
100.times { playlist.add(create(:song)) }
|
123
128
|
|
124
129
|
expect {
|
125
|
-
playlist.shuffle
|
130
|
+
playlist.shuffle!
|
126
131
|
}.to change {
|
127
132
|
playlist.queue.first
|
128
133
|
}
|
@@ -147,4 +152,30 @@ describe Walkman::Playlist do
|
|
147
152
|
expect(playlist.size).to eq(3)
|
148
153
|
end
|
149
154
|
end
|
155
|
+
|
156
|
+
describe "#feedback" do
|
157
|
+
it "updates favorites" do
|
158
|
+
args = { session_id: "ABC123", favorite_song: [song.echonest_song_id], favorite_artist: [song.echonest_artist_id] }
|
159
|
+
|
160
|
+
expect(Walkman.echowrap).to receive(:playlist_dynamic_feedback).with(args)
|
161
|
+
|
162
|
+
playlist.feedback(:favorite, song)
|
163
|
+
end
|
164
|
+
|
165
|
+
it "updates unplay counts" do
|
166
|
+
args = { session_id: "ABC123", unplay_song: [song.echonest_song_id] }
|
167
|
+
|
168
|
+
expect(Walkman.echowrap).to receive(:playlist_dynamic_feedback).with(args)
|
169
|
+
|
170
|
+
playlist.feedback(:unplay, song)
|
171
|
+
end
|
172
|
+
|
173
|
+
it "updates skip counts" do
|
174
|
+
args = { session_id: "ABC123", skip_song: [song.echonest_song_id] }
|
175
|
+
|
176
|
+
expect(Walkman.echowrap).to receive(:playlist_dynamic_feedback).with(args)
|
177
|
+
|
178
|
+
playlist.feedback(:skip, song)
|
179
|
+
end
|
180
|
+
end
|
150
181
|
end
|
@@ -0,0 +1,30 @@
|
|
1
|
+
require "spec_helper"
|
2
|
+
|
3
|
+
describe Walkman do
|
4
|
+
before :each do
|
5
|
+
Walkman.class_variable_set("@@logger", nil) # reset logger
|
6
|
+
end
|
7
|
+
|
8
|
+
describe ".logger" do
|
9
|
+
it "sets the log level according to config.log_level" do
|
10
|
+
expect(Walkman.logger.level).to eq(Walkman.log_level(Walkman.config.log_level))
|
11
|
+
end
|
12
|
+
|
13
|
+
it "allows symbols when setting log level" do
|
14
|
+
[:debug, :info, :warn, :error, :fatal].each do |level|
|
15
|
+
Walkman.class_variable_set("@@logger", nil) # reset logger
|
16
|
+
Walkman.config.log_level = level
|
17
|
+
|
18
|
+
expect(Walkman.logger.level).to eq(Walkman.log_level(level))
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
it "raises an error if an incorrect log level is set" do
|
23
|
+
Walkman.config.log_level = :foo
|
24
|
+
|
25
|
+
expect {
|
26
|
+
Walkman.logger.level
|
27
|
+
}.to raise_error(RuntimeError)
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
data/walkman.gemspec
CHANGED
@@ -2,7 +2,7 @@
|
|
2
2
|
|
3
3
|
Gem::Specification.new do |spec|
|
4
4
|
spec.name = "walkman"
|
5
|
-
spec.version = "0.1.
|
5
|
+
spec.version = "0.1.2"
|
6
6
|
|
7
7
|
spec.author = "Tres Trantham"
|
8
8
|
spec.email = "tres@trestrantham.com"
|
@@ -14,7 +14,7 @@ Gem::Specification.new do |spec|
|
|
14
14
|
spec.files = `git ls-files`.split($/)
|
15
15
|
spec.test_files = spec.files.grep(/^spec/)
|
16
16
|
spec.require_paths = ["lib"]
|
17
|
-
spec.executables =
|
17
|
+
spec.executables = "walkman"
|
18
18
|
|
19
19
|
spec.add_development_dependency "bundler", "~> 1.3"
|
20
20
|
spec.add_development_dependency "rake", "~> 10.1"
|
metadata
CHANGED
@@ -1,149 +1,150 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: walkman
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Tres Trantham
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2013-12-
|
11
|
+
date: 2013-12-28 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
15
15
|
requirement: !ruby/object:Gem::Requirement
|
16
16
|
requirements:
|
17
|
-
- - ~>
|
17
|
+
- - "~>"
|
18
18
|
- !ruby/object:Gem::Version
|
19
19
|
version: '1.3'
|
20
20
|
type: :development
|
21
21
|
prerelease: false
|
22
22
|
version_requirements: !ruby/object:Gem::Requirement
|
23
23
|
requirements:
|
24
|
-
- - ~>
|
24
|
+
- - "~>"
|
25
25
|
- !ruby/object:Gem::Version
|
26
26
|
version: '1.3'
|
27
27
|
- !ruby/object:Gem::Dependency
|
28
28
|
name: rake
|
29
29
|
requirement: !ruby/object:Gem::Requirement
|
30
30
|
requirements:
|
31
|
-
- - ~>
|
31
|
+
- - "~>"
|
32
32
|
- !ruby/object:Gem::Version
|
33
33
|
version: '10.1'
|
34
34
|
type: :development
|
35
35
|
prerelease: false
|
36
36
|
version_requirements: !ruby/object:Gem::Requirement
|
37
37
|
requirements:
|
38
|
-
- - ~>
|
38
|
+
- - "~>"
|
39
39
|
- !ruby/object:Gem::Version
|
40
40
|
version: '10.1'
|
41
41
|
- !ruby/object:Gem::Dependency
|
42
42
|
name: activemodel
|
43
43
|
requirement: !ruby/object:Gem::Requirement
|
44
44
|
requirements:
|
45
|
-
- - ~>
|
45
|
+
- - "~>"
|
46
46
|
- !ruby/object:Gem::Version
|
47
47
|
version: 4.0.2
|
48
48
|
type: :runtime
|
49
49
|
prerelease: false
|
50
50
|
version_requirements: !ruby/object:Gem::Requirement
|
51
51
|
requirements:
|
52
|
-
- - ~>
|
52
|
+
- - "~>"
|
53
53
|
- !ruby/object:Gem::Version
|
54
54
|
version: 4.0.2
|
55
55
|
- !ruby/object:Gem::Dependency
|
56
56
|
name: colorize
|
57
57
|
requirement: !ruby/object:Gem::Requirement
|
58
58
|
requirements:
|
59
|
-
- - ~>
|
59
|
+
- - "~>"
|
60
60
|
- !ruby/object:Gem::Version
|
61
61
|
version: 0.6.0
|
62
62
|
type: :runtime
|
63
63
|
prerelease: false
|
64
64
|
version_requirements: !ruby/object:Gem::Requirement
|
65
65
|
requirements:
|
66
|
-
- - ~>
|
66
|
+
- - "~>"
|
67
67
|
- !ruby/object:Gem::Version
|
68
68
|
version: 0.6.0
|
69
69
|
- !ruby/object:Gem::Dependency
|
70
70
|
name: command
|
71
71
|
requirement: !ruby/object:Gem::Requirement
|
72
72
|
requirements:
|
73
|
-
- - ~>
|
73
|
+
- - "~>"
|
74
74
|
- !ruby/object:Gem::Version
|
75
75
|
version: '1.0'
|
76
76
|
type: :runtime
|
77
77
|
prerelease: false
|
78
78
|
version_requirements: !ruby/object:Gem::Requirement
|
79
79
|
requirements:
|
80
|
-
- - ~>
|
80
|
+
- - "~>"
|
81
81
|
- !ruby/object:Gem::Version
|
82
82
|
version: '1.0'
|
83
83
|
- !ruby/object:Gem::Dependency
|
84
84
|
name: echowrap
|
85
85
|
requirement: !ruby/object:Gem::Requirement
|
86
86
|
requirements:
|
87
|
-
- - ~>
|
87
|
+
- - "~>"
|
88
88
|
- !ruby/object:Gem::Version
|
89
89
|
version: 0.1.0
|
90
90
|
type: :runtime
|
91
91
|
prerelease: false
|
92
92
|
version_requirements: !ruby/object:Gem::Requirement
|
93
93
|
requirements:
|
94
|
-
- - ~>
|
94
|
+
- - "~>"
|
95
95
|
- !ruby/object:Gem::Version
|
96
96
|
version: 0.1.0
|
97
97
|
- !ruby/object:Gem::Dependency
|
98
98
|
name: sinatra
|
99
99
|
requirement: !ruby/object:Gem::Requirement
|
100
100
|
requirements:
|
101
|
-
- - ~>
|
101
|
+
- - "~>"
|
102
102
|
- !ruby/object:Gem::Version
|
103
103
|
version: 1.4.4
|
104
104
|
type: :runtime
|
105
105
|
prerelease: false
|
106
106
|
version_requirements: !ruby/object:Gem::Requirement
|
107
107
|
requirements:
|
108
|
-
- - ~>
|
108
|
+
- - "~>"
|
109
109
|
- !ruby/object:Gem::Version
|
110
110
|
version: 1.4.4
|
111
111
|
- !ruby/object:Gem::Dependency
|
112
112
|
name: thor
|
113
113
|
requirement: !ruby/object:Gem::Requirement
|
114
114
|
requirements:
|
115
|
-
- - ~>
|
115
|
+
- - "~>"
|
116
116
|
- !ruby/object:Gem::Version
|
117
117
|
version: 0.18.1
|
118
118
|
type: :runtime
|
119
119
|
prerelease: false
|
120
120
|
version_requirements: !ruby/object:Gem::Requirement
|
121
121
|
requirements:
|
122
|
-
- - ~>
|
122
|
+
- - "~>"
|
123
123
|
- !ruby/object:Gem::Version
|
124
124
|
version: 0.18.1
|
125
125
|
- !ruby/object:Gem::Dependency
|
126
126
|
name: titleize
|
127
127
|
requirement: !ruby/object:Gem::Requirement
|
128
128
|
requirements:
|
129
|
-
- - ~>
|
129
|
+
- - "~>"
|
130
130
|
- !ruby/object:Gem::Version
|
131
131
|
version: 1.3.0
|
132
132
|
type: :runtime
|
133
133
|
prerelease: false
|
134
134
|
version_requirements: !ruby/object:Gem::Requirement
|
135
135
|
requirements:
|
136
|
-
- - ~>
|
136
|
+
- - "~>"
|
137
137
|
- !ruby/object:Gem::Version
|
138
138
|
version: 1.3.0
|
139
139
|
description: Control your music
|
140
140
|
email: tres@trestrantham.com
|
141
|
-
executables:
|
141
|
+
executables:
|
142
|
+
- walkman
|
142
143
|
extensions: []
|
143
144
|
extra_rdoc_files: []
|
144
145
|
files:
|
145
|
-
- .gitignore
|
146
|
-
- .travis.yml
|
146
|
+
- ".gitignore"
|
147
|
+
- ".travis.yml"
|
147
148
|
- Gemfile
|
148
149
|
- LICENSE.txt
|
149
150
|
- README.md
|
@@ -156,6 +157,7 @@ files:
|
|
156
157
|
- lib/walkman/commands/playlist.rb
|
157
158
|
- lib/walkman/commands/queueing.rb
|
158
159
|
- lib/walkman/config.rb
|
160
|
+
- lib/walkman/logger.rb
|
159
161
|
- lib/walkman/player.rb
|
160
162
|
- lib/walkman/playlist.rb
|
161
163
|
- lib/walkman/services/base.rb
|
@@ -165,20 +167,26 @@ files:
|
|
165
167
|
- spec/factories/echowrap.rb
|
166
168
|
- spec/factories/playlist.rb
|
167
169
|
- spec/factories/song.rb
|
170
|
+
- spec/fixtures/walkman.yml
|
168
171
|
- spec/sinatra_helper.rb
|
169
172
|
- spec/spec_helper.rb
|
170
173
|
- spec/support/factory_girl.rb
|
174
|
+
- spec/support/rspec.rb
|
171
175
|
- spec/walkman/commands/controls_spec.rb
|
172
176
|
- spec/walkman/commands/information_spec.rb
|
173
177
|
- spec/walkman/commands/player_spec.rb
|
178
|
+
- spec/walkman/commands/playlist_spec.rb
|
174
179
|
- spec/walkman/commands/queueing_spec.rb
|
180
|
+
- spec/walkman/config_spec.rb
|
175
181
|
- spec/walkman/player_spec.rb
|
176
182
|
- spec/walkman/playlist_spec.rb
|
177
183
|
- spec/walkman/services/base_spec.rb
|
178
184
|
- spec/walkman/services/rdio/rdio_player_spec.rb
|
179
185
|
- spec/walkman/services/rdio_spec.rb
|
180
186
|
- spec/walkman/song_spec.rb
|
187
|
+
- spec/walkman_spec.rb
|
181
188
|
- walkman.gemspec
|
189
|
+
- bin/walkman
|
182
190
|
homepage: https://github.com/trestrantham/walkman
|
183
191
|
licenses:
|
184
192
|
- MIT
|
@@ -189,12 +197,12 @@ require_paths:
|
|
189
197
|
- lib
|
190
198
|
required_ruby_version: !ruby/object:Gem::Requirement
|
191
199
|
requirements:
|
192
|
-
- -
|
200
|
+
- - ">="
|
193
201
|
- !ruby/object:Gem::Version
|
194
202
|
version: '0'
|
195
203
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
196
204
|
requirements:
|
197
|
-
- -
|
205
|
+
- - ">="
|
198
206
|
- !ruby/object:Gem::Version
|
199
207
|
version: '0'
|
200
208
|
requirements: []
|
@@ -207,16 +215,21 @@ test_files:
|
|
207
215
|
- spec/factories/echowrap.rb
|
208
216
|
- spec/factories/playlist.rb
|
209
217
|
- spec/factories/song.rb
|
218
|
+
- spec/fixtures/walkman.yml
|
210
219
|
- spec/sinatra_helper.rb
|
211
220
|
- spec/spec_helper.rb
|
212
221
|
- spec/support/factory_girl.rb
|
222
|
+
- spec/support/rspec.rb
|
213
223
|
- spec/walkman/commands/controls_spec.rb
|
214
224
|
- spec/walkman/commands/information_spec.rb
|
215
225
|
- spec/walkman/commands/player_spec.rb
|
226
|
+
- spec/walkman/commands/playlist_spec.rb
|
216
227
|
- spec/walkman/commands/queueing_spec.rb
|
228
|
+
- spec/walkman/config_spec.rb
|
217
229
|
- spec/walkman/player_spec.rb
|
218
230
|
- spec/walkman/playlist_spec.rb
|
219
231
|
- spec/walkman/services/base_spec.rb
|
220
232
|
- spec/walkman/services/rdio/rdio_player_spec.rb
|
221
233
|
- spec/walkman/services/rdio_spec.rb
|
222
234
|
- spec/walkman/song_spec.rb
|
235
|
+
- spec/walkman_spec.rb
|