Skip to content

Commit

Permalink
Add Airfoil and Speaker models for upcoming Airfoil integration.
Browse files Browse the repository at this point in the history
These additions cover most of the Airfoil functionality that we will be
using. There is some functionality that has yet to be implemented,
however as the API end is built out any lacking functionality will be
realized and implemented.
  • Loading branch information
joeyw committed Mar 12, 2012
1 parent d448c38 commit a20da90
Show file tree
Hide file tree
Showing 5 changed files with 225 additions and 0 deletions.
2 changes: 2 additions & 0 deletions app/boot.rb
Expand Up @@ -24,6 +24,8 @@
require 'models/queue'
require 'models/song'
require 'models/user'
require 'models/speaker'
require 'models/airfoil'

require 'app'
require 'views/layout'
Expand Down
48 changes: 48 additions & 0 deletions app/models/airfoil.rb
@@ -0,0 +1,48 @@
module Play
class Airfoil

# Get appscript handle for airfoil.
#
# Returns an Appscript instance of the airfoil app.
def self.app
Appscript.app('Airfoil')
end

# Check if Airfoil is installed.
#
# Returns Boolean.
def self.installed?
Dir.exists?('/Applications/Airfoil.app')
end

# Get all the connected speakers.
#
# This can't be named simply speakers because Airfoil
# has a speakers method.
#
# Returns Array of Speakers.
def self.get_speakers
app.speakers.id_.get.map { |id|
Speaker.new id
}
end

# Get volume for all speakers.
#
# Returns Array of Floats speaker volumefrom 0.0 to 1.0.
def self.speakers_volume
app.speakers.volume.get
end

# Set the volume for all speakers.
#
# setting - Float 0.0 to 1.0 volume level.
#
# Returns Float volume level.
def self.speakers_volume=(setting)
app.speakers.volume.set setting
speakers_volume
end

end
end
83 changes: 83 additions & 0 deletions app/models/speaker.rb
@@ -0,0 +1,83 @@
module Play
class Speaker

# The Airfoil ID for the speaker.
attr_reader :id

# Initialize a new speaker.
#
# id - Airfoil id of the speaker.
#
# Returns new Speaker.
def initialize(id)
@id = id
end

# Get appscript handle for airfoil.
#
# Returns Airfoil appscript handle.
def app
Airfoil.app
end

# Get the speaker name.
#
# Returns String speaker name.
def name
app.speakers.ID(@id).name.get
end

# Check if the speaker is connected to an audio source.
#
# Returns boolean.
def connected?
app.speakers.ID(@id).connected.get
end

# Connect the speaker to the audio source.
#
# Returns Boolean connected?
def connect!
app.speakers.ID(@id).connect_to
connected?
end

# Disconnect the speaker from audio source.
#
# Returns Boolean connected?
def disconnect!
app.speakers.ID(@id).disconnect_from
connected?
end

# Get volume for a specific speaker.
#
# Returns Float volume level from 0.0 to 1.0.
def volume
app.speakers.ID(@id).volume.get
end

# Set the volume for a specific speaker.
#
# setting - Float 0.0 to 1.0 volume level.
#
# Returns Float new volume level.
def volume=(setting)
app.speakers.ID(@id).volume.set setting
volume
end

# The hashed representation of a Speaker.
#
# Returns a Hash.
def to_hash
{
:id => @id,
:name => name,
:connected => connected?,
:volume => volume
}
end

end
end
42 changes: 42 additions & 0 deletions test/airfoil_test.rb
@@ -0,0 +1,42 @@
require File.expand_path("../helper", __FILE__)

if !Airfoil.installed?
puts "\nAirfoil is not installed, skipping Airfoil tests."
puts "You can get Airfoil from http://rogueamoeba.com/airfoil/\n\n"
end

context "Airfoil" do

setup do
Airfoil.app.get
@speaker = Speaker.new "com.rogueamoeba.airfoil.LocalSpeaker"
end

test "Get speakers" do
speakers = Airfoil.get_speakers
assert speakers.length > 0
assert_equal @speaker.id, speakers[0].id
assert_equal @speaker.name, speakers[0].name
assert_equal @speaker.connected?, speakers[0].connected?
assert_equal @speaker.volume, speakers[0].volume
end

test "All speaker volumes getting and setting" do
speakers = Airfoil.get_speakers
Airfoil.speakers_volume = 0
speakers.each do |speaker|
assert_equal 0, speaker.volume
end

Airfoil.speakers_volume = 1
speakers.each do |speaker|
assert_equal 1, speaker.volume
end

Airfoil.speakers_volume = 0
speakers.each do |speaker|
assert_equal 0, speaker.volume
end
end

end if Airfoil.installed? and ENV['CI'] != '1'
50 changes: 50 additions & 0 deletions test/speaker_test.rb
@@ -0,0 +1,50 @@
require File.expand_path("../helper", __FILE__)

if !Airfoil.installed?
puts "\nAirfoil is not installed, skipping Speaker tests."
puts "You can get Airfoil from http://rogueamoeba.com/airfoil/\n\n"
end

context "Speaker" do

setup do
Airfoil.app.get
@speaker = Speaker.new "com.rogueamoeba.airfoil.LocalSpeaker"
end

test "speaker id is set" do
assert_equal "com.rogueamoeba.airfoil.LocalSpeaker", @speaker.id
end

test "get speaker name" do
assert_equal "Computer", @speaker.name
end

test "Speaker volume setting and getting" do
@speaker.volume = 0
assert_equal 0, @speaker.volume

@speaker.volume = 1
assert_equal 1, @speaker.volume
end

test "speaker connect, disconnect and connected status" do
@speaker.disconnect!
assert_equal false, @speaker.connected?

@speaker.connect!
assert @speaker.connected?

@speaker.disconnect!
assert_equal false, @speaker.connected?
end

test "speaker to hash" do
speaker = @speaker.to_hash
assert_equal @speaker.id, speaker[:id]
assert_equal @speaker.name, speaker[:name]
assert_equal @speaker.connected?, speaker[:connected]
assert_equal @speaker.volume, speaker[:volume]
end

end if Airfoil.installed? and ENV['CI'] != '1'

0 comments on commit a20da90

Please sign in to comment.