anyplayer 1.1.1 → 1.2.0

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.
@@ -1,77 +1,87 @@
1
1
  class Anyplayer::Xmms2 < Anyplayer::Player
2
2
  def playpause
3
- xmms2 'toggle'
3
+ xmms2 "toggle"
4
4
  end
5
5
 
6
6
  def play
7
- xmms2 'play'
7
+ xmms2 "play"
8
8
  end
9
9
 
10
10
  def pause
11
- xmms2 'pause'
11
+ xmms2 "pause"
12
12
  end
13
13
 
14
14
  def prev
15
- xmms2 'prev'
15
+ xmms2 "prev"
16
16
  super
17
17
  end
18
18
 
19
19
  def next
20
- xmms2 'next'
20
+ xmms2 "next"
21
21
  super
22
22
  end
23
23
 
24
24
  def voldown
25
- current = volume.to_i
26
- new_volume = (current < 11 ? 0 : current - 10)
27
- xmms2 "server volume #{new_volume}"
25
+ set_volume volume - 10
28
26
  end
29
27
 
30
28
  def volup
31
- current = volume.to_i
32
- new_volume = (current > 89 ? 100 : current + 10)
33
- xmms2 "server volume #{new_volume}"
29
+ set_volume volume + 10
34
30
  end
35
31
 
36
32
  def volume
37
33
  # currently just the first (left?) channel
38
- xmms2('server volume').split("\n").first.sub(/([^0-9]*)/, '')
39
- $1
34
+ xmms2("server volume").split("\n").first.sub(/([^0-9]*)/, "").to_i
40
35
  end
41
36
 
42
37
  def track
43
- xmms2 "status -f '${title}'"
38
+ xmms2 "current -f '${title}'"
44
39
  end
45
40
 
46
41
  def artist
47
- xmms2 "status -f '${artist}'"
42
+ xmms2 "current -f '${artist}'"
48
43
  end
49
44
 
50
45
  def album
51
- xmms2 "status -f '${album}'"
46
+ xmms2 "current -f '${album}'"
52
47
  end
53
48
 
54
49
  def playing?
55
- xmms2("status -f '${playback_status}'") == "Playing"
50
+ xmms2("current -f '${playback_status}'") == "Playing"
56
51
  end
57
52
 
58
53
  def paused?
59
- xmms2("status -f '${playback_status}'") == "Paused"
54
+ xmms2("current -f '${playback_status}'") == "Paused"
60
55
  end
61
56
 
62
57
  def launched?
63
58
  # xmms2 autolaunches the daemon, so this should always be true
64
- %x(xmms2 status 2> /dev/null)
59
+ %x(xmms2 current 2> /dev/null)
65
60
  $? == 0
66
61
  end
67
62
 
68
63
  def host
69
- ENV['XMMS_PATH'] || super
64
+ ENV["XMMS_PATH"] || super
65
+ end
66
+
67
+ def platforms
68
+ [:unix, :linux]
70
69
  end
71
70
 
72
71
  private
73
- def xmms2(command)
74
- %x(xmms2 #{command}).split("\n").first.strip
75
- end
76
- end
77
72
 
73
+ def xmms2(command)
74
+ ret = %x(xmms2 #{command}).split("\n").first
75
+ ret ? ret.strip : ""
76
+ end
77
+
78
+ def set_volume(num)
79
+ num = if num < 0
80
+ 0
81
+ elsif num > 100
82
+ 100
83
+ end
84
+
85
+ xmms2 "server volume #{num}"
86
+ end
87
+ end
@@ -1,4 +1,7 @@
1
- # The Selector is the tool that will find you the currently running player on your platform
1
+ require "rbconfig"
2
+
3
+ # The Selector is the tool that will find you the currently running player
4
+ # on your platform.
2
5
  #
3
6
  # Example:
4
7
  #
@@ -7,62 +10,90 @@
7
10
  # player = selector.player
8
11
  #
9
12
  # Needs the PLAYERS constant to contain a list of players.
13
+ module Anyplayer
14
+ class Selector
15
+ attr_accessor :verbose
16
+ attr_reader :errors
10
17
 
11
- class Anyplayer::Selector
12
- attr_accessor :verbose
13
- attr_reader :errors
18
+ def initialize
19
+ @verbose = false
20
+ @errors = []
21
+ end
14
22
 
15
- def initialize
16
- @verbose = false
17
- @errors = []
18
- end
23
+ # Returns an instance of the first music player that's launched
24
+ def player
25
+ PLAYERS.each do |player|
26
+ player_load(player) || next
19
27
 
20
- # Returns an instance of the first music player that's launched
21
- def player
22
- players_for_this_platform.each { |player|
23
- player_load(player) or next
24
- instance = player_class(player).new
25
- return instance if player_launched(instance)
26
- }
27
- nil
28
- end
28
+ instance = player_class(player).new
29
+ player_on_platform?(instance) || next
29
30
 
31
+ return instance if player_launched?(instance)
32
+ end
33
+ nil
34
+ end
30
35
 
31
- private
36
+ private
32
37
 
33
- def players_for_this_platform
34
- players = Anyplayer::PLAYERS
35
- players.reject! { |player| player =~ /_mac$/ } if RUBY_PLATFORM !~ /darwin/
36
- players.reject! { |player| player =~ /_windows$/ } if RUBY_PLATFORM !~ /cygwin|mswin|mingw|bccwin|wince|emx/
37
- players
38
+ def platform
39
+ @platform ||= begin
40
+ host_os = RbConfig::CONFIG["host_os"]
41
+ case host_os
42
+ when /mswin|msys|mingw|cygwin|bccwin|wince|emc/
43
+ :windows
44
+ when /darwin|mac os/
45
+ :mac
46
+ when /linux/
47
+ :linux
48
+ when /solaris|bsd/
49
+ :unix
50
+ else
51
+ @errors << "Unknown operating system #{host_os.inspect}"
52
+ nil
53
+ end
54
+ end
38
55
  end
39
56
 
40
57
  def player_load(player)
58
+ log "#{player}:"
41
59
  begin
42
60
  require "anyplayer/players/#{player}"
43
- $stderr.puts "Loaded #{player}" if verbose
61
+ log " loaded"
44
62
  true
45
63
  rescue LoadError => e
46
- $stderr.puts "Could not load #{player}" if verbose
64
+ log " #{e.message}"
47
65
  @errors << "Error loading #{player}: #{e.message}"
48
66
  false
49
67
  end
50
68
  end
51
69
 
52
- def player_class(player)
53
- camelized = player.to_s.split(/_/).map{ |word| word.capitalize }.join
54
- Anyplayer::const_get(camelized)
70
+ def player_on_platform?(player)
71
+ result = player.platforms.include?(platform)
72
+ log " not on platform" unless result
73
+ result
55
74
  end
56
75
 
57
- def player_launched(player)
58
- $stderr.puts "#{player.name} launched?" if verbose
76
+ def player_class(player)
77
+ camelized = player.to_s.split(/_/).map(&:capitalize).join
78
+ Anyplayer.const_get(camelized)
79
+ end
59
80
 
81
+ def player_launched?(player)
60
82
  seconds = 5
61
83
  begin
62
- Timeout::timeout(seconds) { player.launched? }
84
+ Timeout.timeout(seconds) do
85
+ launched = player.launched?
86
+ log launched ? " launched" : " not launched"
87
+ launched
88
+ end
63
89
  rescue Timeout::Error
64
- $stderr.puts "Timed out after #{seconds} seconds" if verbose
90
+ log " timed out after #{seconds} seconds"
65
91
  false
66
92
  end
67
93
  end
94
+
95
+ def log(text)
96
+ $stderr.puts text if verbose
97
+ end
98
+ end
68
99
  end
@@ -1,3 +1,3 @@
1
1
  module Anyplayer
2
- VERSION = "1.1.1"
2
+ VERSION = "1.2.0"
3
3
  end
@@ -1,9 +1,15 @@
1
1
  require "test_helper"
2
2
 
3
- class AnyplayerTest < MiniTest::Unit::TestCase
4
- # def test_loading_all_players_does_not_explode
5
- # PLAYERS.each do |player|
6
- # require "anyplayer/players/#{player}"
7
- # end
8
- # end
3
+ class AnyplayerTest < Minitest::Test
4
+ def test_loading_all_players_does_not_explode
5
+ PLAYERS.each do |player|
6
+ require "anyplayer/players/#{player}"
7
+ end
8
+ rescue LoadError
9
+ # Allow LoadErrors that depend on Windows
10
+ end
11
+
12
+ def test_launched
13
+ assert_kind_of Anyplayer::Player, Anyplayer.launched
14
+ end
9
15
  end
@@ -0,0 +1,150 @@
1
+ require "test_helper"
2
+ require "anyplayer/command_line"
3
+
4
+ class CommandLineTest < Minitest::Test
5
+ USAGE = "Usage: anyplayer [-v] [command]
6
+
7
+ Where command is one of: playpause, play, pause, next, prev, voldown, volup, volume, track, artist, album, vote, name, launched, paused, playing.
8
+
9
+ Player connected: Fake Player.
10
+ "
11
+
12
+ def setup
13
+ @player = flexmock(:player)
14
+ @selector = flexmock(:selector)
15
+ @selector.should_receive(:player).and_return(@player)
16
+ flexmock(Anyplayer::Selector).should_receive(:new).and_return(@selector)
17
+ end
18
+
19
+ def test_no_command
20
+ flexmock(@player).should_receive(:name).once.and_return("Fake Player")
21
+ flexmock($stderr).should_receive(:puts).once.with(USAGE)
22
+ flexmock(Anyplayer::CommandLine).should_receive(:exit).once.with(1)
23
+ Anyplayer::CommandLine.parse(%w())
24
+ end
25
+
26
+ def test_wrong_command
27
+ flexmock(@player).should_receive(:name).once.and_return("Fake Player")
28
+ flexmock($stderr).should_receive(:puts).once.with(USAGE)
29
+ flexmock(Anyplayer::CommandLine).should_receive(:exit).once.with(1)
30
+ Anyplayer::CommandLine.parse(%w(err))
31
+ end
32
+
33
+ def test_verbose
34
+ # flexmock(@player).should_receive(:name).once.and_return("Foo")
35
+ flexmock(@player).should_receive(:play).once
36
+ flexmock(@selector).should_receive(:verbose=).once.with(true)
37
+ flexmock($stderr).should_receive(:puts).once.with(/^anyplayer v[0-9.]+$/)
38
+ Anyplayer::CommandLine.parse(%w(-v play))
39
+ end
40
+
41
+ # Actions
42
+
43
+ def test_playpause
44
+ flexmock(@player).should_receive(:playpause).once
45
+ Anyplayer::CommandLine.parse(%w(playpause))
46
+ end
47
+
48
+ def test_play
49
+ flexmock(@player).should_receive(:play).once
50
+ Anyplayer::CommandLine.parse(%w(play))
51
+ end
52
+
53
+ def test_pause
54
+ flexmock(@player).should_receive(:pause).once
55
+ Anyplayer::CommandLine.parse(%w(pause))
56
+ end
57
+
58
+ def test_next
59
+ flexmock(@player).should_receive(:next).once
60
+ Anyplayer::CommandLine.parse(%w(next))
61
+ end
62
+
63
+ def test_prev
64
+ flexmock(@player).should_receive(:prev).once
65
+ Anyplayer::CommandLine.parse(%w(prev))
66
+ end
67
+
68
+ def test_voldown
69
+ flexmock(@player).should_receive(:voldown).once
70
+ Anyplayer::CommandLine.parse(%w(voldown))
71
+ end
72
+
73
+ def test_volup
74
+ flexmock(@player).should_receive(:volup).once
75
+ Anyplayer::CommandLine.parse(%w(volup))
76
+ end
77
+
78
+ def test_vote
79
+ flexmock(@player).should_receive(:vote).once
80
+ Anyplayer::CommandLine.parse(%w(vote))
81
+ end
82
+
83
+ def test_volume
84
+ flexmock(@player).should_receive(:volume).once.and_return(42)
85
+ flexmock($stdout).should_receive(:puts).once.with(42)
86
+ Anyplayer::CommandLine.parse(%w(volume))
87
+ end
88
+
89
+ def test_track
90
+ flexmock(@player).should_receive(:track).once.and_return("Foo")
91
+ flexmock($stdout).should_receive(:puts).once.with("Foo")
92
+ Anyplayer::CommandLine.parse(%w(track))
93
+ end
94
+
95
+ def test_artist
96
+ flexmock(@player).should_receive(:artist).once.and_return("Foo")
97
+ flexmock($stdout).should_receive(:puts).once.with("Foo")
98
+ Anyplayer::CommandLine.parse(%w(artist))
99
+ end
100
+
101
+ def test_album
102
+ flexmock(@player).should_receive(:album).once.and_return("Foo")
103
+ flexmock($stdout).should_receive(:puts).once.with("Foo")
104
+ Anyplayer::CommandLine.parse(%w(album))
105
+ end
106
+
107
+ def test_name
108
+ flexmock(@player).should_receive(:name).once.and_return("Foo")
109
+ flexmock($stdout).should_receive(:puts).once.with("Foo")
110
+ Anyplayer::CommandLine.parse(%w(name))
111
+ end
112
+
113
+ # Booleans
114
+
115
+ def test_launched_true
116
+ flexmock(Anyplayer::CommandLine).should_receive(:exit) # .with(1)
117
+ flexmock(@player).should_receive(:launched?).once.and_return(true)
118
+ Anyplayer::CommandLine.parse(%w(launched))
119
+ end
120
+
121
+ def test_launched_false
122
+ flexmock(Anyplayer::CommandLine).should_receive(:exit) # .with(0)
123
+ flexmock(@player).should_receive(:launched?).once.and_return(false)
124
+ Anyplayer::CommandLine.parse(%w(launched))
125
+ end
126
+
127
+ def test_playing_true
128
+ flexmock(Anyplayer::CommandLine).should_receive(:exit).once # .with(1)
129
+ flexmock(@player).should_receive(:playing?).once.and_return(true)
130
+ Anyplayer::CommandLine.parse(%w(playing))
131
+ end
132
+
133
+ def test_playing_false
134
+ flexmock(Anyplayer::CommandLine).should_receive(:exit).once # .with(0)
135
+ flexmock(@player).should_receive(:playing?).once.and_return(false)
136
+ Anyplayer::CommandLine.parse(%w(playing))
137
+ end
138
+
139
+ def test_paused_true
140
+ flexmock(Anyplayer::CommandLine).should_receive(:exit).once # .with(1)
141
+ flexmock(@player).should_receive(:paused?).once.and_return(true)
142
+ Anyplayer::CommandLine.parse(%w(paused))
143
+ end
144
+
145
+ def test_paused_false
146
+ flexmock(Anyplayer::CommandLine).should_receive(:exit).once # .with(0)
147
+ flexmock(@player).should_receive(:paused?).once.and_return(false)
148
+ Anyplayer::CommandLine.parse(%w(paused))
149
+ end
150
+ end
@@ -1,12 +1,51 @@
1
1
  require "test_helper"
2
2
 
3
- class PlayerTest < MiniTest::Unit::TestCase
4
- include FlexMock::TestCase
5
-
3
+ class PlayerTest < Minitest::Test
6
4
  def setup
7
5
  @player = Noplayer.new
8
6
  end
9
7
 
8
+ # Default name
9
+
10
+ def test_default_name
11
+ assert_equal "Noplayer", @player.name
12
+ end
13
+
14
+ def test_default_name_should_remove_namespace
15
+ flexmock(@player).should_receive(:class).and_return("Foo::Bar")
16
+ assert_equal "Bar", @player.name
17
+ end
18
+
19
+ # Default paused?
20
+
21
+ def test_paused_is_false_if_not_playing
22
+ flexmock(@player).should_receive(:playing?).once.and_return(false)
23
+ assert @player.paused?
24
+ end
25
+
26
+ def test_paused_is_true_if_not_paused
27
+ flexmock(@player).should_receive(:playing?).once.and_return(true)
28
+ assert !@player.paused?
29
+ end
30
+
31
+ # Default playpause
32
+
33
+ def test_playpause_toggles_play
34
+ flexmock(@player).should_receive(:paused?).once.and_return(true)
35
+ flexmock(@player).should_receive(:play).once
36
+
37
+ @player.playpause
38
+ end
39
+
40
+ def test_playpause_toggles_pause
41
+ flexmock(@player).should_receive(:paused?).once.and_return(false)
42
+ flexmock(@player).should_receive(:pause).once
43
+
44
+ @player.playpause
45
+ end
46
+
47
+ # Votes
48
+
10
49
  def test_votes
11
50
  Player::DEFAULT_VOTES_TO_SKIP.times do |i|
12
51
  @player.vote
@@ -16,7 +55,7 @@ class PlayerTest < MiniTest::Unit::TestCase
16
55
  assert_equal @player.votes, 0
17
56
  else
18
57
  assert_equal @player.votes, i + 1
19
- end
58
+ end
20
59
  end
21
60
  end
22
61
 
@@ -45,9 +84,7 @@ class PlayerTest < MiniTest::Unit::TestCase
45
84
  assert_equal @player.votes, 0
46
85
  else
47
86
  assert_equal @player.votes, i + 1
48
- end
87
+ end
49
88
  end
50
89
  end
51
-
52
-
53
90
  end