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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 8e3d7ee1e1eeb85342fc9df700432e1a1879cf58
4
- data.tar.gz: 7538521e2f9691d497aa9f780279fe6034d995d0
3
+ metadata.gz: 428f899c2b92b174d1e6693ee29932c5a9cd94e9
4
+ data.tar.gz: 5c352d5761efddeddfa5e685dfa4f081845473dc
5
5
  SHA512:
6
- metadata.gz: fb245267ddb8f2c75c0cf3711ee9d4006df6c2deefed5985cabb458d0b0bd38a48d6cce3c04fdca97ab3fa0fa397838cc2d9c14f6c2af7571a3bb657471cb20f
7
- data.tar.gz: 549890eeb0a29f384329909e17d59d71ac0b69060489aad7d19f55a97a0adb0461e74d0b16f8f67a21cf2c7945e3b5e039ee25e2012314d33ad689182b4f7ef9
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
@@ -0,0 +1,5 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require "walkman"
4
+
5
+ Walkman::CLI.start
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
- thread = Thread.new do
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, { count: count.to_i })
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, { count: count.to_i })
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, { artist: 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, { artist: artist })
90
+ response = server.run_command(:artist_radio, artist: artist)
94
91
  puts response unless response.empty?
95
92
  end
96
93
 
@@ -17,7 +17,7 @@ module Walkman
17
17
 
18
18
  def self.next(count = 1)
19
19
  if current_song = Walkman.player.current_song
20
- Walkman.player.playlist.skip(current_song)
20
+ Walkman.player.playlist.feedback(:skip, current_song)
21
21
  end
22
22
 
23
23
  Walkman.player.next(count)
@@ -6,12 +6,21 @@ module Walkman
6
6
  playlist = Walkman.player.playlist
7
7
 
8
8
  if current_song && playlist
9
- playlist.favorite(current_song)
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 = Walkman::Playlist.new(type: "artist", artist: artist, auto_queue: true)
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 = Walkman::Playlist.new(type: "artist-radio", artist: artist, auto_queue: true)
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
@@ -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)
@@ -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 && self.next
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(songs)
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 unplay(songs)
68
- songs = [songs].flatten # one or more
69
-
70
- songs.each do |song|
71
- echonest_playlist_feedback({ unplay_song: song.echonest_song_id })
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
- songs.each do |song|
79
- echonest_playlist_feedback({ skip_song: song.echonest_song_id, unplay_song: song.echonest_song_id })
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
- def favorite(songs)
84
- songs = [songs].flatten # one or more
76
+ args[:unplay_song] = song_ids if types.include?(:unplay)
77
+ args[:skip_song] = song_ids if types.include?(:skip)
85
78
 
86
- songs.each do |song|
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(options = {})
94
- return nil unless options.keys.include?(:type)
84
+ def echonest_playlist_create(args = {})
85
+ return nil unless args.keys.include?(:type)
95
86
 
96
- options[:bucket] = ["id:rdio-US", "tracks"]
97
- options[:seed_catalog] = Walkman.config.echonest_catalog_id
98
- options[:session_catalog] = Walkman.config.echonest_catalog_id
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(options)
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
- result.songs.each do |song|
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
- next unless track
126
-
127
- songs << Walkman::Song.new(artist: song.artist_name,
128
- title: song.title,
129
- source_type: "Walkman::Services::Rdio",
130
- source_id: track.foreign_id.split(":").last,
131
- echonest_artist_id: song.artist_id,
132
- echonest_song_id: song.id)
133
- end
134
-
135
- add(songs)
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("Implement in Service")
5
+ raise "Implement in Service"
6
6
  end
7
7
 
8
8
  def shutdown
9
- raise("Implement in Service")
9
+ raise "Implement in Service"
10
10
  end
11
11
 
12
12
  def restart
13
- raise("Implement in Service")
13
+ raise "Implement in Service"
14
14
  end
15
15
 
16
16
  def play(song)
17
- raise("Implement in Service")
17
+ raise "Implement in Service"
18
18
  end
19
19
 
20
20
  def stop
21
- raise("Implement in Service")
21
+ raise "Implement in Service"
22
22
  end
23
23
  end
24
24
  end
@@ -12,6 +12,7 @@ module Walkman
12
12
  def shutdown
13
13
  Walkman.logger.debug "stopping Rdio service"
14
14
 
15
+ quit_browser
15
16
  @player_thread.terminate if @player_thread
16
17
  end
17
18
 
@@ -0,0 +1,13 @@
1
+ log_level: info
2
+ server:
3
+ host: localhost
4
+ port: 27001
5
+ echonest:
6
+ api_key: ABC
7
+ consumer_key: DEF
8
+ shared_secret: GHI
9
+ catalog_id: JKL
10
+ rdio:
11
+ playback_token: MNO
12
+ player_url: http://localhost:1/rdio
13
+ browser_path: /path/to/browser
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.logger.level = Walkman.log_level(:info)
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
@@ -0,0 +1,5 @@
1
+ RSpec.configure do |config|
2
+ config.mock_with :rspec do |c|
3
+ c.syntax = [:should, :expect]
4
+ end
5
+ 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
@@ -3,9 +3,22 @@ require "spec_helper"
3
3
  describe Walkman::Player do
4
4
  let!(:player) { Walkman.player }
5
5
 
6
- after :each do
7
- player.shutdown
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.stub(:startup)
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 be_false
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 be_true
43
- expect(playlist.queued?(song)).to be_true
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 be_false
48
- expect(playlist.queued?(song)).to be_false
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.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 = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
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.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-22 00:00:00.000000000 Z
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