walkman 0.1.1 → 0.1.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/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
|