anyplayer 0.0.2 → 0.0.3

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,3 +1,4 @@
1
1
  language: ruby
2
2
  rvm:
3
3
  - 1.9.3
4
+ - 2.0.0
@@ -1,11 +1,12 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- anyplayer (0.0.2)
4
+ anyplayer (0.0.3)
5
5
 
6
6
  GEM
7
7
  remote: http://rubygems.org/
8
8
  specs:
9
+ flexmock (0.9.0)
9
10
  minitest (4.1.0)
10
11
  rake (0.9.2.2)
11
12
 
@@ -14,5 +15,6 @@ PLATFORMS
14
15
 
15
16
  DEPENDENCIES
16
17
  anyplayer!
18
+ flexmock
17
19
  minitest
18
20
  rake
data/Rakefile CHANGED
@@ -6,6 +6,7 @@ Bundler::GemHelper.install_tasks
6
6
  task :default => :test
7
7
 
8
8
  Rake::TestTask.new do |t|
9
+ t.libs << "test"
9
10
  t.pattern = "test/*_test.rb"
10
11
  t.verbose = true
11
12
  end
@@ -42,7 +42,7 @@ Or in Ruby
42
42
 
43
43
  ```ruby
44
44
  require 'anyplayer'
45
- player = Anyplayer::launched
45
+ player = Anyplayer::Selector.new.player
46
46
 
47
47
  player.launched? # => true
48
48
  player.name # => Rythmbox
@@ -58,14 +58,26 @@ With the [So Nice](https://github.com/sunny/so-nice/) Web interface:
58
58
 
59
59
  ![So Nice Screenshot](https://github.com/sunny/so-nice/raw/gh-pages/screenshot.png)
60
60
 
61
+
61
62
  Development
62
63
  -----------
63
64
 
64
- Launch from source:
65
+ Depending on your configuration you may need to add `bundle exec` to the following commands.
66
+
67
+ Terminal binary from source:
68
+
69
+ ```sh
70
+ $ ruby -Ilib bin/anyplayer
71
+ ```
72
+
73
+ Tests:
65
74
 
66
- ruby -Ilib bin/anyplayer
75
+ ```sh
76
+ $ rake test
77
+ ```
67
78
 
68
79
  Install from source:
69
80
 
70
- gem build anyplayer.gemspec
71
- gem install anyplayer-*.gem
81
+ ```sh
82
+ $ rake install
83
+ ```
@@ -18,4 +18,5 @@ Gem::Specification.new do |s|
18
18
  s.require_paths = ["lib"]
19
19
 
20
20
  s.add_development_dependency 'minitest'
21
+ s.add_development_dependency 'flexmock'
21
22
  end
@@ -1,14 +1,19 @@
1
1
  #!/usr/bin/env ruby
2
- # -*- encoding: utf-8 -*-
3
- require 'anyplayer'
4
2
 
5
- player = Anyplayer::launched
3
+ require 'anyplayer'
6
4
 
7
- if !player
8
- puts "Error: no player connected."
9
- exit 1
5
+ # Create a selector
6
+ selector = Anyplayer::Selector.new
7
+ if ARGV.first == "-v"
8
+ selector.verbose = true
9
+ ARGV.pop
10
10
  end
11
11
 
12
+ # Find the current player
13
+ player = selector.player
14
+ abort "Error: no player connected.\n" + selector.errors.join("\n") if !player
15
+
16
+ # Call it
12
17
  case ARGV.first
13
18
  when "playpause" then player.playpause
14
19
  when "play" then player.play
@@ -28,7 +33,7 @@ case ARGV.first
28
33
  when "paused" then exit(player.playing? ? 0 : 1)
29
34
  else
30
35
  puts <<USAGE
31
- Usage: #{$0} [command]
36
+ Usage: #{$0} [-v] [command]
32
37
 
33
38
  Where command is one of: playpause, play, pause, next, prev, voldown, volup,
34
39
  volume, track, artist, album, vote, name, launched.
@@ -36,4 +41,4 @@ volume, track, artist, album, vote, name, launched.
36
41
  Player connected: #{player.name}.
37
42
  USAGE
38
43
  exit(1)
39
- end
44
+ end
@@ -1,24 +1,23 @@
1
1
  require "timeout"
2
- require "anyplayer/player"
3
2
 
4
3
  module Anyplayer
5
- PLAYERS = [:itunes, :rhythmbox, :ituneswindows, :mpd, :xmms2, :amarok]
6
- for player in PLAYERS
7
- require "anyplayer/players/#{player}"
8
- end
4
+ PLAYERS = %w(
5
+ rhythmbox
6
+ mpd
7
+ xmms2
8
+ amarok
9
+ itunes_mac
10
+ itunes_windows
11
+ spotify_mac
12
+ )
9
13
 
10
- # Return the first music player that's launched
11
- def self::launched(verbose = false)
12
- PLAYERS.each { |player|
13
- player = const_get(player.to_s.capitalize).new
14
- puts "Trying #{player.name}..." if verbose
15
-
16
- begin
17
- Timeout::timeout(5) { return player if player.launched? }
18
- rescue Timeout::Error
19
- puts "Timed out" if verbose
20
- end
21
- }
22
- nil
14
+ def self.launched
15
+ $stderr.puts "Anyplayer.launched is deprecated: please initialize a new Selector and call player"
16
+ Selector.new.player
23
17
  end
24
18
  end
19
+
20
+ require "anyplayer/player"
21
+ require "anyplayer/selector"
22
+
23
+
@@ -15,55 +15,61 @@
15
15
  # volume (return int)
16
16
  # playing? (return bool)
17
17
  # paused? (return bool)
18
- module Anyplayer
19
- class Player
20
- DEFAULT_VOTES_TO_SKIP = 5
18
+ class Anyplayer::Player
19
+ DEFAULT_VOTES_TO_SKIP = 5
21
20
 
22
- def initialize
23
- @votes = 0
24
- end
25
-
26
- def launched?
27
- false
28
- end
29
-
30
- # Player name is the classe's, feel free to override it
31
- def name
32
- self.class.to_s.gsub(/^.*::/, '')
33
- end
21
+ def initialize
22
+ @votes = 0
23
+ end
34
24
 
35
- def playpause
36
- paused? ? play : pause
37
- end
25
+ # Return true if the player is currently launched
26
+ def launched?
27
+ false
28
+ end
38
29
 
39
- # Vote to skip song
40
- def vote(votes_to_skip = DEFAULT_VOTES_TO_SKIP)
41
- @votes += 1
42
- if @votes >= votes_to_skip
43
- self.next
44
- reset_votes
45
- end
46
- end
30
+ # Player name defaults to the classe's, feel free to override it
31
+ # Example:
32
+ # player.name # => iTunes
33
+ def name
34
+ self.class.to_s.gsub(/^.*::/, '')
35
+ end
47
36
 
48
- def votes
49
- @votes
50
- end
37
+ # Tells the player to toggle the pause state
38
+ def playpause
39
+ paused? ? play : pause
40
+ end
51
41
 
52
- # Root next and prev reset the votes, so be sure to call super
53
- # in children
54
- def next
42
+ # Vote to skip this song
43
+ def vote(votes_to_skip = DEFAULT_VOTES_TO_SKIP)
44
+ @votes += 1
45
+ if @votes >= votes_to_skip
46
+ self.next
55
47
  reset_votes
56
48
  end
49
+ end
57
50
 
58
- def prev
59
- reset_votes
60
- end
51
+ # Returns the number of votes to skip this song
52
+ def votes
53
+ @votes
54
+ end
61
55
 
62
- private
63
- def reset_votes
64
- @votes = 0
65
- end
56
+ # Tell the player to go the the next song
57
+ # This resets the votes, so be sure to call super in children
58
+ def next
59
+ reset_votes
60
+ end
66
61
 
62
+ # Tell the player to go to the previous song
63
+ # This resets the votes, so be sur eto call super in children
64
+ def prev
65
+ reset_votes
67
66
  end
67
+
68
+ private
69
+
70
+ def reset_votes
71
+ @votes = 0
72
+ end
73
+
68
74
  end
69
75
 
@@ -1,63 +1,61 @@
1
- module Anyplayer
2
- class Amarok < Player
3
- def playpause
4
- tell_to 'PlayPause'
5
- end
1
+ class Anyplayer::Amarok < Anyplayer::Player
2
+ def playpause
3
+ amarok 'PlayPause'
4
+ end
6
5
 
7
- def play
8
- tell_to 'Play'
9
- end
6
+ def play
7
+ amarok 'Play'
8
+ end
10
9
 
11
- def pause
12
- tell_to 'Pause'
13
- end
10
+ def pause
11
+ amarok 'Pause'
12
+ end
14
13
 
15
- def prev
16
- tell_to 'Prev'
17
- super
18
- end
14
+ def prev
15
+ amarok 'Prev'
16
+ super
17
+ end
19
18
 
20
- def next
21
- tell_to 'Next'
22
- super
23
- end
19
+ def next
20
+ amarok 'Next'
21
+ super
22
+ end
24
23
 
25
- def voldown
26
- tell_to 'VolumeDown 5'
27
- end
24
+ def voldown
25
+ amarok 'VolumeDown 5'
26
+ end
28
27
 
29
- def volup
30
- tell_to 'VolumeUp 5'
31
- end
28
+ def volup
29
+ amarok 'VolumeUp 5'
30
+ end
32
31
 
33
- def volume
34
- tell_to 'VolumeGet'
35
- end
32
+ def volume
33
+ amarok 'VolumeGet'
34
+ end
36
35
 
37
- def track
38
- get_metadata('title')
39
- end
36
+ def track
37
+ amarok_get_meta 'title'
38
+ end
40
39
 
41
- def artist
42
- get_metadata('artist')
43
- end
40
+ def artist
41
+ amarok_get_meta 'artist'
42
+ end
44
43
 
45
- def album
46
- get_metadata('album')
47
- end
44
+ def album
45
+ amarok_get_meta 'album'
46
+ end
48
47
 
49
- def launched?
50
- not %x(qdbus org.kde.amarok 2>&1).match(/does not exist|command not found/)
51
- end
48
+ def launched?
49
+ not %x(qdbus org.kde.amarok 2>&1).match(/does not exist|command not found/)
50
+ end
52
51
 
53
- private
54
- def tell_to(command)
52
+ private
53
+ def amarok(command)
55
54
  %x(qdbus org.kde.amarok /Player org.freedesktop.MediaPlayer.#{command}).rstrip
56
55
  end
57
56
 
58
- def get_metadata(name)
59
- tell_to('GetMetadata').match(/#{name}: (\S.*)/)[1] rescue nil
57
+ def amarok_get_meta(name)
58
+ amarok('GetMetadata').match(/#{name}: (\S.*)/)[1] rescue nil
60
59
  end
61
- end
62
60
  end
63
61
 
@@ -0,0 +1,53 @@
1
+ class Anyplayer::ItunesMac < Anyplayer::Player
2
+ def playpause
3
+ itunes 'playpause'
4
+ end
5
+
6
+ def prev
7
+ itunes 'previous track'
8
+ super
9
+ end
10
+
11
+ def next
12
+ itunes 'next track'
13
+ super
14
+ end
15
+
16
+ def voldown
17
+ itunes 'set sound volume to sound volume - 10'
18
+ end
19
+
20
+ def volup
21
+ itunes 'set sound volume to sound volume + 10'
22
+ end
23
+
24
+ def volume
25
+ itunes 'return sound volume'
26
+ end
27
+
28
+ def track
29
+ itunes 'return name of current track'
30
+ end
31
+
32
+ def artist
33
+ itunes 'return artist of current track'
34
+ end
35
+
36
+ def album
37
+ itunes 'return album of current track'
38
+ end
39
+
40
+ def launched?
41
+ nb = %x(osascript -e 'tell app "System Events" to count (every process whose name is "iTunes")' 2>/dev/null).rstrip
42
+ nb.match(/^\d+/) and nb.to_i > 0 ? true : false
43
+ end
44
+
45
+ def name
46
+ "iTunes Mac"
47
+ end
48
+
49
+ private
50
+ def itunes(command)
51
+ %x(osascript -e 'tell app "iTunes" to #{command}').rstrip
52
+ end
53
+ end
@@ -0,0 +1,68 @@
1
+ begin
2
+ require 'win32ole'
3
+ rescue LoadError => e
4
+ raise LoadError.new("#{e.message} -- You probably aren't on Windows")
5
+ end
6
+
7
+ class Anyplayer::ItunesWindows < Anyplayer::Player
8
+ def playpause
9
+ itunes.PlayPause()
10
+ end
11
+
12
+ def play
13
+ itunes.Play()
14
+ end
15
+
16
+ def pause
17
+ itunes.Pause()
18
+ end
19
+
20
+ def prev
21
+ itunes.PreviousTrack()
22
+ super
23
+ end
24
+
25
+ def next
26
+ itunes.NextTrack()
27
+ super
28
+ end
29
+
30
+ def voldown
31
+ itunes.SoundVolume = itunes.SoundVolume - 10
32
+ end
33
+
34
+ def volup
35
+ itunes.SoundVolume = itunes.SoundVolume + 10
36
+ end
37
+
38
+ def volume
39
+ itunes.SoundVolume
40
+ end
41
+
42
+ def track
43
+ itunes.CurrentTrack.name
44
+ end
45
+
46
+ def artist
47
+ itunes.CurrentTrack.Artist
48
+ end
49
+
50
+ def album
51
+ itunes.CurrentTrack.Album
52
+ end
53
+
54
+ def launched?
55
+ itunes
56
+ end
57
+
58
+ def name
59
+ "iTunes Windows"
60
+ end
61
+
62
+ private
63
+
64
+ def itunes
65
+ itunes ||= WIN32OLE.new("iTunes.Application")
66
+ end
67
+ end
68
+