airplay 1.0.0.beta3 → 1.0.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.
@@ -2,7 +2,6 @@ language: ruby
2
2
  rvm:
3
3
  - "1.9.3"
4
4
  - "2.0.0"
5
- - "rbx-19mode"
6
5
  before_install:
7
6
  - "sudo apt-get -qq update"
8
7
  - "sudo apt-get -qq install rdnssd libavahi-compat-libdnssd-dev"
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- airplay (1.0.0.beta3)
4
+ airplay (1.0.0)
5
5
  CFPropertyList (~> 2.2.0)
6
6
  celluloid (~> 0.15.0)
7
7
  cuba (~> 3.1.0)
data/README.md CHANGED
@@ -24,11 +24,11 @@ much as you want in: https://gumroad.com/l/airplay
24
24
 
25
25
  ### Library
26
26
 
27
- `gem install airplay --pre`
27
+ `gem install airplay`
28
28
 
29
29
  ## CLI
30
30
 
31
- `gem install airplay-cli --pre`
31
+ `gem install airplay-cli`
32
32
 
33
33
  ## Usage
34
34
 
@@ -37,6 +37,9 @@ much as you want in: https://gumroad.com/l/airplay
37
37
  #### View devices
38
38
 
39
39
  `air list`
40
+
41
+ ![air list](doc/img/cli_list.png)
42
+
40
43
  ```text
41
44
  * Apple TV (AppleTV2,1 running 11A502)
42
45
  ip: 192.168.1.12
@@ -46,6 +49,9 @@ much as you want in: https://gumroad.com/l/airplay
46
49
  #### Play a video
47
50
 
48
51
  `air play [url to video or local file]`
52
+
53
+ ![air play](doc/img/cli_play.png)
54
+
49
55
  ```text
50
56
  Playing http://movietrailers.apple.com/movies/universal/rush/rush-tlr3_480p.mov?width=848&height=352
51
57
  Time: 00:00:13 [===== ] 7% Apple TV
@@ -63,8 +69,8 @@ Time: 00:00:13 [===== ] 7% Apple TV
63
69
  Airplay.configure do |config|
64
70
  config.log_level # Log4r levels (Default: Log4r::ERROR)
65
71
  config.autodiscover # Allows to search for nodes (Default: true)
66
- config.host # In which host bind the server (Default: 0.0.0.0)
67
- config.port # In which port bind the server (Default: 1337)
72
+ config.host # In which host to bind the server (Default: 0.0.0.0)
73
+ config.port # In which port to bind the server (Default: 1337)
68
74
  config.output # Where to log (Default: Log4r::Outputter.stdout)
69
75
  end
70
76
  ```
@@ -77,11 +83,15 @@ require "airplay"
77
83
  Airplay.devices.each do |device|
78
84
  puts device.name
79
85
  end
86
+ ```
80
87
 
81
- # You can access an know device easily
88
+ #### Accesing and Grouping
89
+
90
+ ```ruby
91
+ # You can access a known device easily
82
92
  device = Airplay["Apple TV"]
83
93
 
84
- # Or you can group known devices to have them do a given action toghether
94
+ # Or you can group known devices to have them do a given action together
85
95
  Airplay.group["Backyard"] << Airplay["Apple TV"]
86
96
  Airplay.group["Backyard"] << Airplay["Room TV"]
87
97
 
@@ -165,8 +175,14 @@ player.progress -> progress {
165
175
  }
166
176
  ```
167
177
 
178
+ ## Documentation
179
+
180
+ All the documentation of the README can be found in the `doc` folder.
181
+ To generate an updated README based on the contents of `doc` please use `rake doc:generate`
182
+
168
183
  ## Contributors
169
184
 
170
185
  * [sodabrew](http://github.com/sodabrew)
171
186
  * [pote](http://github.com/pote)
172
-
187
+ * [janogonzalez](http://github.com/janogonzalez) - Who allowed me to release 1.0
188
+ from startech conf <3
data/Rakefile CHANGED
@@ -84,7 +84,7 @@ task :test => [:spec]
84
84
 
85
85
  namespace :doc do
86
86
  task :generate do
87
- structure = %w(header installation usage contributors)
87
+ structure = %w(header installation usage documentation contributors)
88
88
 
89
89
  File.open("README.md", "w+") do |f|
90
90
  structure.each { |part| f << File.read("doc/#{part}.md") + "\n" }
@@ -13,7 +13,7 @@ Gem::Specification.new do |s|
13
13
  s.homepage = "http://github.com/elcuervo/airplay"
14
14
  s.files = %w(bin/air lib/airplay/cli.rb)
15
15
 
16
- s.add_dependency("airplay", "= 1.0.0.beta3")
16
+ s.add_dependency("airplay", "= 1.0.0")
17
17
  s.add_dependency("clap", "~> 1.0.0")
18
18
  s.add_dependency("ruby-progressbar", "~> 1.2.0")
19
19
  end
data/bin/air CHANGED
@@ -2,26 +2,36 @@
2
2
 
3
3
  require "clap"
4
4
  require "airplay/cli"
5
+ require "airplay/cli/version"
5
6
 
6
- Clap.run ARGV,
7
- "--device" => lambda { |device_name| @device = Airplay[device_name] },
8
- "--wait" => lambda { |sec| @wait = sec.to_i },
9
- "--interactive" => lambda { @interactive = true },
7
+ begin
8
+ Clap.run ARGV,
9
+ "--device" => lambda { |device_name| @device = Airplay[device_name] },
10
+ "--wait" => lambda { |sec| @wait = sec.to_i },
11
+ "--interactive" => lambda { @interactive = true },
10
12
 
11
- "list" => Airplay::CLI.method(:list),
13
+ "list" => Airplay::CLI.method(:list),
12
14
 
13
- "play" => lambda { |video|
14
- options = { device: @device || Airplay.devices.first }
15
- Airplay::CLI.play(video, options)
16
- },
15
+ "version" => lambda { puts Airplay::CLI::VERSION },
17
16
 
18
- "view" => lambda { |file|
19
- options = {
20
- device: @device || Airplay.devices.first,
21
- interactive: @interactive || false,
22
- wait: @wait || 3
17
+ "play" => lambda { |video|
18
+ options = { device: @device || Airplay.devices.first }
19
+ Airplay::CLI.play(video, options)
20
+ },
21
+
22
+ "view" => lambda { |file|
23
+ options = {
24
+ device: @device || Airplay.devices.first,
25
+ interactive: @interactive || false,
26
+ wait: @wait || 3
27
+ }
28
+ Airplay::CLI.view(file, options)
23
29
  }
24
- Airplay::CLI.view(file, options)
25
- }
30
+
31
+ rescue Airplay::Browser::NoDevicesFound
32
+ puts "No devices found."
33
+ rescue Interrupt
34
+ puts "Bye!"
35
+ end
26
36
 
27
37
  # vim: ft=ruby
@@ -0,0 +1,4 @@
1
+ ## Documentation
2
+
3
+ All the documentation of the README can be found in the `doc` folder.
4
+ To generate an updated README based on the contents of `doc` please use `rake doc:generate`
Binary file
Binary file
@@ -5,6 +5,9 @@
5
5
  #### View devices
6
6
 
7
7
  `air list`
8
+
9
+ ![air list](doc/img/cli_list.png)
10
+
8
11
  ```text
9
12
  * Apple TV (AppleTV2,1 running 11A502)
10
13
  ip: 192.168.1.12
@@ -14,6 +17,9 @@
14
17
  #### Play a video
15
18
 
16
19
  `air play [url to video or local file]`
20
+
21
+ ![air play](doc/img/cli_play.png)
22
+
17
23
  ```text
18
24
  Playing http://movietrailers.apple.com/movies/universal/rush/rush-tlr3_480p.mov?width=848&height=352
19
25
  Time: 00:00:13 [===== ] 7% Apple TV
@@ -31,8 +37,8 @@ Time: 00:00:13 [===== ] 7% Apple TV
31
37
  Airplay.configure do |config|
32
38
  config.log_level # Log4r levels (Default: Log4r::ERROR)
33
39
  config.autodiscover # Allows to search for nodes (Default: true)
34
- config.host # In which host bind the server (Default: 0.0.0.0)
35
- config.port # In which port bind the server (Default: 1337)
40
+ config.host # In which host to bind the server (Default: 0.0.0.0)
41
+ config.port # In which port to bind the server (Default: 1337)
36
42
  config.output # Where to log (Default: Log4r::Outputter.stdout)
37
43
  end
38
44
  ```
@@ -45,11 +51,15 @@ require "airplay"
45
51
  Airplay.devices.each do |device|
46
52
  puts device.name
47
53
  end
54
+ ```
55
+
56
+ #### Accesing and Grouping
48
57
 
49
- # You can access an know device easily
58
+ ```ruby
59
+ # You can access a known device easily
50
60
  device = Airplay["Apple TV"]
51
61
 
52
- # Or you can group known devices to have them do a given action toghether
62
+ # Or you can group known devices to have them do a given action together
53
63
  Airplay.group["Backyard"] << Airplay["Apple TV"]
54
64
  Airplay.group["Backyard"] << Airplay["Room TV"]
55
65
 
@@ -8,22 +8,44 @@ require "airplay/version"
8
8
  #
9
9
  module Airplay
10
10
  class << self
11
+ # Public: General configuration
12
+ #
13
+ # &block - The block that will modify the configuration
14
+ #
15
+ # Returns the configuration file.
16
+ #
11
17
  def configure(&block)
12
18
  yield(configuration) if block
13
19
  end
14
20
 
21
+ # Public: Access the server object
22
+ #
23
+ # Returns the Server object
24
+ #
15
25
  def server
16
26
  @_server ||= Server.new
17
27
  end
18
28
 
29
+ # Public: Browses for devices in the current network
30
+ #
31
+ # Returns nothing.
32
+ #
19
33
  def browse
20
34
  browser.browse
21
35
  end
22
36
 
37
+ # Public: Access or create a group based on a key
38
+ #
39
+ # Returns the Hash object.
40
+ #
23
41
  def group
24
42
  @_group ||= Hash.new { |h, k| h[k] = Group.new(k) }
25
43
  end
26
44
 
45
+ # Public: Helper method to access all the devices
46
+ #
47
+ # Returns a Group with all the devices.
48
+ #
27
49
  def all
28
50
  @_all ||= begin
29
51
  group = Group.new(:all)
@@ -32,23 +54,39 @@ module Airplay
32
54
  end
33
55
  end
34
56
 
35
- # Public: Lists found devices
57
+ # Public: Lists found devices if autodiscover is enabled
58
+ #
59
+ # Returns an Array with all the devices
36
60
  #
37
61
  def devices
38
62
  browse if browser.devices.empty? && configuration.autodiscover
39
63
  browser.devices
40
64
  end
41
65
 
66
+ # Public: Access the configuration object
67
+ #
68
+ # Returns the Configuration object
69
+ #
42
70
  def configuration
43
71
  @_configuration ||= Configuration.new
44
72
  end
45
73
 
74
+ # Public: Access a device by name
75
+ #
76
+ # device_name - The name to search on the devices
77
+ #
78
+ # Returns the found device
79
+ #
46
80
  def [](device_name)
47
81
  devices.find_by_name(device_name)
48
82
  end
49
83
 
50
84
  private
51
85
 
86
+ # Private: Access the browser object
87
+ #
88
+ # Returns the momoized Browser object
89
+ #
52
90
  def browser
53
91
  @_browser ||= Browser.new
54
92
  end
@@ -8,6 +8,8 @@ module Airplay
8
8
  # Public: Browser class to find Airplay-enabled devices in the network
9
9
  #
10
10
  class Browser
11
+ NoDevicesFound = Class.new(StandardError)
12
+
11
13
  SEARCH = "_airplay._tcp."
12
14
 
13
15
  def initialize
@@ -16,6 +18,8 @@ module Airplay
16
18
 
17
19
  # Public: Browses in the search of devices and adds them to the nodes
18
20
  #
21
+ # Returns nothing or raises NoDevicesFound if there are no devices
22
+ #
19
23
  def browse
20
24
  timeout(5) do
21
25
  DNSSD.browse!(SEARCH) do |node|
@@ -23,10 +27,14 @@ module Airplay
23
27
  break unless node.flags.more_coming?
24
28
  end
25
29
  end
30
+ rescue Timeout::Error => e
31
+ raise NoDevicesFound
26
32
  end
27
33
 
28
34
  # Public: Access to the node list
29
35
  #
36
+ # Returns the Devices list object
37
+ #
30
38
  def devices
31
39
  @_devices ||= Devices.new
32
40
  end
@@ -35,8 +43,8 @@ module Airplay
35
43
 
36
44
  # Private: Resolves a node given a node and a resolver
37
45
  #
38
- # node - The given node
39
- # resolver - The DNSSD::Server that is resolving nodes
46
+ # node - The given node
47
+ # resolver - The DNSSD::Server that is resolving nodes
40
48
  #
41
49
  # Returns if there are more nodes coming
42
50
  #
@@ -56,7 +64,9 @@ module Airplay
56
64
 
57
65
  # Private: Resolves the node information given a node
58
66
  #
59
- # node - The node from the DNSSD browsing
67
+ # node - The node from the DNSSD browsing
68
+ #
69
+ # Returns nothing
60
70
  #
61
71
  def resolve(node)
62
72
  resolver = DNSSD::Service.new
@@ -1,9 +1,18 @@
1
- require "airplay"
2
1
  require "ruby-progressbar"
2
+ require "airplay"
3
+ require "airplay/cli/image_viewer"
3
4
 
5
+ # Public: Airplay core module
6
+ #
4
7
  module Airplay
8
+ # Public: Airplay CLI module
9
+ #
5
10
  module CLI
6
11
  class << self
12
+ # Public: Lists all the devices to STDOUT
13
+ #
14
+ # Returns nothing.
15
+ #
7
16
  def list
8
17
  Airplay.devices.each do |device|
9
18
  puts <<-EOS.gsub(/^\s{12}/,'')
@@ -15,6 +24,14 @@ module Airplay
15
24
  end
16
25
  end
17
26
 
27
+ # Public: Plays a video given a device
28
+ #
29
+ # video - The url or file path to the video
30
+ # options - Options that include the device
31
+ # * device: The device in which it should run
32
+ #
33
+ # Returns nothing.
34
+ #
18
35
  def play(video, options)
19
36
  device = options[:device]
20
37
  player = device.play(video)
@@ -31,74 +48,34 @@ module Airplay
31
48
  player.wait
32
49
  end
33
50
 
51
+ # Public: Show an image given a device
52
+ #
53
+ # file_or_dir - The url, file path or folder path to the image/s
54
+ # options - Options that include the device
55
+ # * device: The device in which it should run
56
+ # * interactive: Boolean flag to control playback with the
57
+ # arrow keys
58
+ #
59
+ # Returns nothing.
60
+ #
34
61
  def view(file_or_dir, options)
35
62
  device = options[:device]
36
- wait = options[:wait]
63
+ viewer = ImageViewer.new(device, options)
37
64
 
38
65
  if File.directory?(file_or_dir)
39
66
  files = Dir.glob("#{file_or_dir}/*")
40
67
 
41
68
  if options[:interactive]
42
- view_interactive(files)
69
+ viewer.interactive(files)
43
70
  else
44
- view_slideshow(files)
71
+ viewer.slideshow(files)
45
72
  end
46
73
  else
47
- view_image(device, file_or_dir)
74
+ viewer.view(file_or_dir)
48
75
  sleep
49
76
  end
50
77
  end
51
78
 
52
- private
53
-
54
- def view_interactive(files)
55
- numbers = Array(0...files.count)
56
- transition = "None"
57
-
58
- i = 0
59
- loop do
60
- view_image(device, files[i], transition)
61
-
62
- case read_char
63
- # Right Arrow
64
- when "\e[C"
65
- i = i + 1 > numbers.count - 1 ? 0 : i + 1
66
- transition = "SlideLeft"
67
- when "\e[D"
68
- i = i - 1 < 0 ? numbers.count - 1 : i - 1
69
- transition = "SlideRight"
70
- else
71
- break
72
- end
73
- end
74
- end
75
-
76
- def view_slideshow(files)
77
- files.each do |file|
78
- view_image(device, file)
79
- sleep wait
80
- end
81
- end
82
-
83
- def read_char
84
- STDIN.echo = false
85
- STDIN.raw!
86
-
87
- input = STDIN.getc.chr
88
- if input == "\e" then
89
- input << STDIN.read_nonblock(3) rescue nil
90
- input << STDIN.read_nonblock(2) rescue nil
91
- end
92
- ensure
93
- STDIN.echo = true
94
- STDIN.cooked!
95
-
96
- return input
97
- end
98
-
99
- def view_image(device, image, transition = "SlideLeft")
100
- device.view(image, transition: transition)
101
- end
102
79
  end
103
80
  end
104
81
  end