Skip to content

Commit

Permalink
Adds doctor command and improve listing
Browse files Browse the repository at this point in the history
  • Loading branch information
elcuervo committed Feb 16, 2014
1 parent 348992e commit 53b9623
Show file tree
Hide file tree
Showing 5 changed files with 105 additions and 11 deletions.
2 changes: 2 additions & 0 deletions bin/air
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@ begin

"list" => Airplay::CLI.method(:list),

"doctor" => Airplay::CLI.method(:doctor),

"version" => Airplay::CLI.method(:version),

"play" => lambda { |video|
Expand Down
17 changes: 17 additions & 0 deletions lib/airplay/cli.rb
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
require "ruby-progressbar"
require "airplay"
require "airplay/cli/image_viewer"
require "airplay/cli/doctor"

# Public: Airplay core module
#
Expand Down Expand Up @@ -28,6 +29,7 @@ def help
version - The current airplay-cli version.
play - Plays a local or remote video.
view - Shows an image or a folder of images, can be an url.
doctor - Shows some debug information to trace bugs.
Options:
Expand All @@ -50,6 +52,7 @@ def list
* #{device.name} (#{device.info.model} running #{device.info.os_version})
ip: #{device.ip}
mac: #{device.id}
password?: #{device.password? ? "yes" : "no"}
type: #{device.type}
resolution: #{device.info.resolution}
Expand Down Expand Up @@ -87,6 +90,20 @@ def play(video, options)
player.wait
end

def doctor
puts <<-EOS.gsub!(" "*10, "")
This will run some basic tests on your network trying to find errors
and debug information to help fix them.
EOS

who = Airplay::CLI::Doctor.new

puts "Running dns-sd tests:"
who.information
end

# Public: Show an image given a device
#
# file_or_dir - The url, file path or folder path to the image/s
Expand Down
60 changes: 60 additions & 0 deletions lib/airplay/cli/doctor.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
module Airplay
module CLI
class Doctor
DebugDevice = Struct.new(:node, :resolved) do
def host
info = Socket.getaddrinfo(resolved.target, nil, Socket::AF_INET)
info[0][2]
rescue SocketError
target
end
end

attr_accessor :devices

def initialize
@devices = []
end

def information
find_devices!

devices.each do |device|
puts <<-EOS.gsub!(" "*12, "")
Name: #{device.node.name}
Host: #{device.host}
Port: #{device.resolved.port}
Full Name: #{device.node.fullname}
Iface: #{device.node.interface_name}
TXT: #{device.resolved.text_record}
EOS
end
end

private

def find_devices!
timeout(5) do
DNSSD.browse!(Airplay::Browser::SEARCH) do |node|
try_resolving(node)
break unless node.flags.more_coming?
end
end
end

def try_resolving(node)
timeout(5) do
resolver = DNSSD::Service.new
resolver.resolve(node) do |resolved|
devices << DebugDevice.new(node, resolved)

break unless resolved.flags.more_coming?
end
end
end


end
end
end
4 changes: 2 additions & 2 deletions lib/airplay/connection.rb
Original file line number Diff line number Diff line change
Expand Up @@ -137,8 +137,8 @@ def send_request(request, headers)
#
def verify_response(response)
if response.response.status == 401
raise PasswordRequired if !@device.password?
raise WrongPassword if @device.password?
return PasswordRequired.new if !@device.password?
return WrongPassword.new if @device.password?
end

response
Expand Down
33 changes: 24 additions & 9 deletions lib/airplay/device.rb
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,8 @@ def initialize(attributes = {})
@type = attributes[:type]
@password = attributes[:password]

@it_has_password = false

Airplay.configuration.load
end

Expand Down Expand Up @@ -62,6 +64,7 @@ def password=(passwd)
# Returns boolean for the presence of a password
#
def password?
return @it_has_password if @it_has_password
!!password && !password.empty?
end

Expand Down Expand Up @@ -127,6 +130,10 @@ def id

private

def it_has_password!
@it_has_password = true
end

# Private: Access the basic info of the device
#
# Returns a hash with the basic information
Expand All @@ -146,17 +153,25 @@ def basic_info
# Returns a hash with extra information
#
def extra_info
@_extra_info ||= begin
new_device = clone
new_device.refresh_connection
new_device.address = "#{ip}:7100"
@_extra_info ||=
begin
new_device = clone
new_device.refresh_connection
new_device.address = "#{ip}:7100"

response = new_device.connection.get("/stream.xml").response
return {} if response.status != 200
result = new_device.connection.get("/stream.xml")
raise result if !result.is_a?(Airplay::Connection::Response)

plist = CFPropertyList::List.new(data: response.body)
CFPropertyList.native_types(plist.value)
end
response = result.response
return {} if response.status != 200

plist = CFPropertyList::List.new(data: response.body)
CFPropertyList.native_types(plist.value)
rescue Airplay::Connection::PasswordRequired
it_has_password!

return {}
end
end

# Private: Validates the mandatory attributes for a device
Expand Down

0 comments on commit 53b9623

Please sign in to comment.