ws_discovery 0.0.1

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.
Files changed (60) hide show
  1. data/Gemfile +2 -0
  2. data/History.rdoc +3 -0
  3. data/README.rdoc +77 -0
  4. data/Rakefile +16 -0
  5. data/lib/ws_discovery/core_ext/socket_patch.rb +16 -0
  6. data/lib/ws_discovery/error.rb +4 -0
  7. data/lib/ws_discovery/multicast_connection.rb +77 -0
  8. data/lib/ws_discovery/network_constants.rb +13 -0
  9. data/lib/ws_discovery/response.rb +95 -0
  10. data/lib/ws_discovery/searcher.rb +91 -0
  11. data/lib/ws_discovery/version.rb +3 -0
  12. data/lib/ws_discovery.rb +61 -0
  13. data/spec/spec_helper.rb +26 -0
  14. data/spec/ws_discovery/coverage/assets/0.7.1/application.css +1110 -0
  15. data/spec/ws_discovery/coverage/assets/0.7.1/application.js +626 -0
  16. data/spec/ws_discovery/coverage/assets/0.7.1/fancybox/blank.gif +0 -0
  17. data/spec/ws_discovery/coverage/assets/0.7.1/fancybox/fancy_close.png +0 -0
  18. data/spec/ws_discovery/coverage/assets/0.7.1/fancybox/fancy_loading.png +0 -0
  19. data/spec/ws_discovery/coverage/assets/0.7.1/fancybox/fancy_nav_left.png +0 -0
  20. data/spec/ws_discovery/coverage/assets/0.7.1/fancybox/fancy_nav_right.png +0 -0
  21. data/spec/ws_discovery/coverage/assets/0.7.1/fancybox/fancy_shadow_e.png +0 -0
  22. data/spec/ws_discovery/coverage/assets/0.7.1/fancybox/fancy_shadow_n.png +0 -0
  23. data/spec/ws_discovery/coverage/assets/0.7.1/fancybox/fancy_shadow_ne.png +0 -0
  24. data/spec/ws_discovery/coverage/assets/0.7.1/fancybox/fancy_shadow_nw.png +0 -0
  25. data/spec/ws_discovery/coverage/assets/0.7.1/fancybox/fancy_shadow_s.png +0 -0
  26. data/spec/ws_discovery/coverage/assets/0.7.1/fancybox/fancy_shadow_se.png +0 -0
  27. data/spec/ws_discovery/coverage/assets/0.7.1/fancybox/fancy_shadow_sw.png +0 -0
  28. data/spec/ws_discovery/coverage/assets/0.7.1/fancybox/fancy_shadow_w.png +0 -0
  29. data/spec/ws_discovery/coverage/assets/0.7.1/fancybox/fancy_title_left.png +0 -0
  30. data/spec/ws_discovery/coverage/assets/0.7.1/fancybox/fancy_title_main.png +0 -0
  31. data/spec/ws_discovery/coverage/assets/0.7.1/fancybox/fancy_title_over.png +0 -0
  32. data/spec/ws_discovery/coverage/assets/0.7.1/fancybox/fancy_title_right.png +0 -0
  33. data/spec/ws_discovery/coverage/assets/0.7.1/fancybox/fancybox-x.png +0 -0
  34. data/spec/ws_discovery/coverage/assets/0.7.1/fancybox/fancybox-y.png +0 -0
  35. data/spec/ws_discovery/coverage/assets/0.7.1/fancybox/fancybox.png +0 -0
  36. data/spec/ws_discovery/coverage/assets/0.7.1/favicon_green.png +0 -0
  37. data/spec/ws_discovery/coverage/assets/0.7.1/favicon_red.png +0 -0
  38. data/spec/ws_discovery/coverage/assets/0.7.1/favicon_yellow.png +0 -0
  39. data/spec/ws_discovery/coverage/assets/0.7.1/loading.gif +0 -0
  40. data/spec/ws_discovery/coverage/assets/0.7.1/magnify.png +0 -0
  41. data/spec/ws_discovery/coverage/assets/0.7.1/smoothness/images/ui-bg_flat_0_aaaaaa_40x100.png +0 -0
  42. data/spec/ws_discovery/coverage/assets/0.7.1/smoothness/images/ui-bg_flat_75_ffffff_40x100.png +0 -0
  43. data/spec/ws_discovery/coverage/assets/0.7.1/smoothness/images/ui-bg_glass_55_fbf9ee_1x400.png +0 -0
  44. data/spec/ws_discovery/coverage/assets/0.7.1/smoothness/images/ui-bg_glass_65_ffffff_1x400.png +0 -0
  45. data/spec/ws_discovery/coverage/assets/0.7.1/smoothness/images/ui-bg_glass_75_dadada_1x400.png +0 -0
  46. data/spec/ws_discovery/coverage/assets/0.7.1/smoothness/images/ui-bg_glass_75_e6e6e6_1x400.png +0 -0
  47. data/spec/ws_discovery/coverage/assets/0.7.1/smoothness/images/ui-bg_glass_95_fef1ec_1x400.png +0 -0
  48. data/spec/ws_discovery/coverage/assets/0.7.1/smoothness/images/ui-bg_highlight-soft_75_cccccc_1x100.png +0 -0
  49. data/spec/ws_discovery/coverage/assets/0.7.1/smoothness/images/ui-icons_222222_256x240.png +0 -0
  50. data/spec/ws_discovery/coverage/assets/0.7.1/smoothness/images/ui-icons_2e83ff_256x240.png +0 -0
  51. data/spec/ws_discovery/coverage/assets/0.7.1/smoothness/images/ui-icons_454545_256x240.png +0 -0
  52. data/spec/ws_discovery/coverage/assets/0.7.1/smoothness/images/ui-icons_888888_256x240.png +0 -0
  53. data/spec/ws_discovery/coverage/assets/0.7.1/smoothness/images/ui-icons_cd0a0a_256x240.png +0 -0
  54. data/spec/ws_discovery/coverage/index.html +72 -0
  55. data/spec/ws_discovery/multicast_connection_spec.rb +108 -0
  56. data/spec/ws_discovery/response_spec.rb +118 -0
  57. data/spec/ws_discovery/searcher_spec.rb +85 -0
  58. data/spec/ws_discovery_spec.rb +43 -0
  59. data/ws_discovery.gemspec +32 -0
  60. metadata +296 -0
@@ -0,0 +1,72 @@
1
+ <!DOCTYPE html>
2
+ <html xmlns='http://www.w3.org/1999/xhtml'>
3
+ <head>
4
+ <title>Code coverage for Ws discovery</title>
5
+ <meta http-equiv="content-type" content="text/html; charset=utf-8" />
6
+ <script src='./assets/0.7.1/application.js' type='text/javascript'></script>
7
+ <link href='./assets/0.7.1/application.css' media='screen, projection, print' rel='stylesheet' type='text/css'>
8
+ <link rel="shortcut icon" type="image/png" href="./assets/0.7.1/favicon_green.png" />
9
+ <link rel="icon" type="image/png" href="./assets/0.7.1/favicon.png" />
10
+ </head>
11
+
12
+ <body>
13
+ <div id="loading">
14
+ <img src="./assets/0.7.1/loading.gif" alt="loading"/>
15
+ </div>
16
+ <div id="wrapper" style="display:none;">
17
+ <div class="timestamp">Generated <abbr class="timeago" title="2012-11-12T13:50:26-08:00">2012-11-12T13:50:26-08:00</abbr></div>
18
+ <ul class="group_tabs"></ul>
19
+
20
+ <div id="content">
21
+ <div class="file_list_container" id="AllFiles">
22
+ <h2>
23
+ <span class="group_name">All Files</span>
24
+ (<span class="covered_percent"><span class="green">100.0%</span></span>
25
+ covered at
26
+ <span class="covered_strength">
27
+ <span class="red">
28
+ 0.0
29
+ </span>
30
+ </span> hits/line)
31
+ </h2>
32
+ <a name="AllFiles"></a>
33
+ <div>
34
+ <b>0</b> files in total.
35
+ <b>0.0</b> relevant lines.
36
+ <span class="green"><b>0.0</b> lines covered</span> and
37
+ <span class="red"><b>0.0</b> lines missed </span>
38
+ </div>
39
+ <table class="file_list">
40
+ <thead>
41
+ <tr>
42
+ <th>File</th>
43
+ <th>% covered</th>
44
+ <th>Lines</th>
45
+ <th>Relevant Lines</th>
46
+ <th>Lines covered</th>
47
+ <th>Lines missed</th>
48
+ <th>Avg. Hits / Line</th>
49
+ </tr>
50
+ </thead>
51
+ <tbody>
52
+
53
+ </tbody>
54
+ </table>
55
+ </div>
56
+
57
+
58
+
59
+ </div>
60
+
61
+ <div id="footer">
62
+ Generated by <a href="http://github.com/colszowka/simplecov">simplecov</a> v0.7.1
63
+ and simplecov-html v0.7.1<br/>
64
+ using RSpec
65
+ </div>
66
+
67
+ <div class="source_files">
68
+
69
+ </div>
70
+ </div>
71
+ </body>
72
+ </html>
@@ -0,0 +1,108 @@
1
+ require 'spec_helper'
2
+ require 'ws_discovery/multicast_connection'
3
+
4
+ describe WSDiscovery::MulticastConnection do
5
+ around(:each) do |example|
6
+ EM.run do
7
+ example.run
8
+ EM.stop
9
+ end
10
+ end
11
+
12
+ subject { WSDiscovery::MulticastConnection.new(1) }
13
+
14
+ describe "#peer_info" do
15
+ before do
16
+ WSDiscovery::MulticastConnection.any_instance.stub(:setup_multicast_socket)
17
+ subject.stub_chain(:get_peername, :[], :unpack).and_return(%w(1234 1 2 3 4))
18
+ end
19
+
20
+ it "returns an Array with IP and port" do
21
+ subject.send(:peer_info).should == ['1.2.3.4', 1234]
22
+ end
23
+
24
+ it "returns IP as a String" do
25
+ subject.send(:peer_info).first.should be_a String
26
+ end
27
+
28
+ it "returns port as a Fixnum" do
29
+ subject.send(:peer_info).last.should be_a Fixnum
30
+ end
31
+ end
32
+
33
+ describe "#setup_multicast_socket" do
34
+ before do
35
+ WSDiscovery::MulticastConnection.any_instance.stub(:set_membership)
36
+ WSDiscovery::MulticastConnection.any_instance.stub(:switch_multicast_loop)
37
+ WSDiscovery::MulticastConnection.any_instance.stub(:set_multicast_ttl)
38
+ WSDiscovery::MulticastConnection.any_instance.stub(:set_ttl)
39
+ end
40
+
41
+ it "adds 0.0.0.0 and 239.255.255.250 to the membership group" do
42
+ subject.should_receive(:set_membership).with(
43
+ IPAddr.new('239.255.255.250').hton + IPAddr.new('0.0.0.0').hton
44
+ )
45
+ subject.send(:setup_multicast_socket)
46
+ end
47
+
48
+ it "sets multicast TTL to 1" do
49
+ subject.should_receive(:set_multicast_ttl).with(1)
50
+ subject.send(:setup_multicast_socket)
51
+ end
52
+
53
+ it "sets TTL to 1" do
54
+ subject.should_receive(:set_ttl).with(1)
55
+ subject.send(:setup_multicast_socket)
56
+ end
57
+
58
+ context "ENV['RUBY_TESTING_ENV'] != testing" do
59
+ after { ENV['RUBY_TESTING_ENV'] = "testing" }
60
+
61
+ it "turns multicast loop off" do
62
+ ENV['RUBY_TESTING_ENV'] = "development"
63
+ subject.should_receive(:switch_multicast_loop).with(:off)
64
+ subject.send(:setup_multicast_socket)
65
+ end
66
+ end
67
+ end
68
+
69
+ describe "#switch_multicast_loop" do
70
+ before do
71
+ WSDiscovery::MulticastConnection.any_instance.stub(:setup_multicast_socket)
72
+ end
73
+
74
+ it "passes '\\001' to the socket option call when param == :on" do
75
+ subject.should_receive(:set_sock_opt).with(
76
+ 0, Socket::IP_MULTICAST_LOOP, "\001"
77
+ )
78
+ subject.send(:switch_multicast_loop, :on)
79
+ end
80
+
81
+ it "passes '\\001' to the socket option call when param == '\\001'" do
82
+ subject.should_receive(:set_sock_opt).with(
83
+ 0, Socket::IP_MULTICAST_LOOP, "\001"
84
+ )
85
+ subject.send(:switch_multicast_loop,"\001")
86
+ end
87
+
88
+ it "passes '\\000' to the socket option call when param == :off" do
89
+ subject.should_receive(:set_sock_opt).with(
90
+ 0, Socket::IP_MULTICAST_LOOP, "\000"
91
+ )
92
+ subject.send(:switch_multicast_loop,:off)
93
+ end
94
+
95
+ it "passes '\\000' to the socket option call when param == '\\000'" do
96
+ subject.should_receive(:set_sock_opt).with(
97
+ 0, Socket::IP_MULTICAST_LOOP, "\000"
98
+ )
99
+ subject.send(:switch_multicast_loop,"\000")
100
+ end
101
+
102
+ it "raises when not :on, :off, '\\000', or '\\001'" do
103
+ expect { subject.send(:switch_multicast_loop, 12312312) }.
104
+ to raise_error(WSDiscovery::Error)
105
+ end
106
+ end
107
+ end
108
+
@@ -0,0 +1,118 @@
1
+ require 'spec_helper'
2
+ require 'ws_discovery/response'
3
+
4
+ describe WSDiscovery::Response do
5
+ let(:probe_response) do
6
+ <<-PROBE
7
+ <s:Envelope xmlns:s="http://www.w3.org/2003/05/soap-envelope"
8
+ xmlns:a="http://schemas.xmlsoap.org/ws/2004/08/addressing"
9
+ xmlns:d="http://schemas.xmlsoap.org/ws/2005/04/discovery">
10
+ <s:Header>
11
+ <a:To>http://schemas.xmlsoap.org/ws/2004/08/addressing/role/anonymous</a:To>
12
+ <a:Action>http://schemas.xmlsoap.org/ws/2005/04/discovery/ProbeMatches</a:Action>
13
+ <a:MessageID>urn:uuid:18523f7e-7a54-d92d-a18d-e7165bec8e7e</a:MessageID>
14
+ <a:RelatesTo>uuid:7dbdede0-0f2b-0130-5861-002564b29b24</a:RelatesTo>
15
+ <d:AppSequence MessageNumber="42" InstanceId="2"/>
16
+ </s:Header>
17
+ <s:Body>
18
+ <d:ProbeMatches>
19
+ <d:ProbeMatch>
20
+ <a:EndpointReference>
21
+ <a:Address>urn:uuid:0b679890-fc54-14ba-d428-f73b3e7c2400</a:Address>
22
+ </a:EndpointReference>
23
+ <d:Types xmlns:dn="http://www.onvif.org/ver10/network/wsdl">dn:NetworkVideoTransmitter</d:Types>
24
+ <d:Scopes>onvif://www.onvif.org/Profile/Streaming onvif://www.onvif.org/hardware/NET5404T onvif://www.onvif.org/type/ptz onvif://www.onvif.org/type/video_encoder onvif://www.onvif.org/location/country/usa onvif://www.onvif.org/name/NET5404T-ABEPZH7</d:Scopes>
25
+ <d:XAddrs>http://10.221.222.74/onvif/device_service</d:XAddrs>
26
+ <d:MetadataVersion>1</d:MetadataVersion>
27
+ </d:ProbeMatch>
28
+ </d:ProbeMatches>
29
+ </s:Body>
30
+ </s:Envelope>
31
+ PROBE
32
+ end
33
+
34
+ let(:probe_body_hash) do
35
+ { probe_matches: {
36
+ probe_match: {
37
+ endpoint_reference: {
38
+ address: "urn:uuid:0b679890-fc54-14ba-d428-f73b3e7c2400" },
39
+ types: "dn:NetworkVideoTransmitter",
40
+ scopes: "onvif://www.onvif.org/Profile/Streaming onvif://www.onvif.org/hardware/NET5404T onvif://www.onvif.org/type/ptz onvif://www.onvif.org/type/video_encoder onvif://www.onvif.org/location/country/usa onvif://www.onvif.org/name/NET5404T-ABEPZH7",
41
+ x_addrs: "http://10.221.222.74/onvif/device_service",
42
+ metadata_version: "1" } } }
43
+ end
44
+
45
+ let(:probe_header_hash) do
46
+ { to: "http://schemas.xmlsoap.org/ws/2004/08/addressing/role/anonymous",
47
+ action: "http://schemas.xmlsoap.org/ws/2005/04/discovery/ProbeMatches",
48
+ message_id: "urn:uuid:18523f7e-7a54-d92d-a18d-e7165bec8e7e",
49
+ relates_to: "uuid:7dbdede0-0f2b-0130-5861-002564b29b24",
50
+ app_sequence: {
51
+ :@message_number => "42",
52
+ :@instance_id => "2" } }
53
+ end
54
+
55
+ let(:probe_full_hash) do
56
+ { envelope: { header: probe_header_hash, body: probe_body_hash,
57
+ :"@xmlns:s" => "http://www.w3.org/2003/05/soap-envelope",
58
+ :"@xmlns:a" => "http://schemas.xmlsoap.org/ws/2004/08/addressing",
59
+ :"@xmlns:d" => "http://schemas.xmlsoap.org/ws/2005/04/discovery" } }
60
+ end
61
+
62
+ subject { WSDiscovery::Response.new(probe_response) }
63
+
64
+ describe "#[]" do
65
+ it "should return the SOAP response body as a Hash" do
66
+ subject[:probe_matches].should == probe_body_hash[:probe_matches]
67
+ end
68
+
69
+ it "should throw an exception when the response body isn't parsable" do
70
+ expect { WSDiscovery::Response.new('').body }.to raise_error WSDiscovery::Error
71
+ end
72
+ end
73
+
74
+ describe "#header" do
75
+ it "should return the SOAP response header as a Hash" do
76
+ subject.header[:app_sequence].should == probe_header_hash[:app_sequence]
77
+ end
78
+
79
+ it "should throw an exception when the response header isn't parsable" do
80
+ expect { WSDiscovery::Response.new('').header }.to raise_error WSDiscovery::Error
81
+ end
82
+ end
83
+
84
+ %w(body to_hash).each do |method|
85
+ describe "##{method}" do
86
+ it "should return the SOAP response body as a Hash" do
87
+ subject.send(method)[:probe_matches].should == probe_body_hash[:probe_matches]
88
+ end
89
+ end
90
+ end
91
+
92
+ describe "#hash" do
93
+ it "should return the complete SOAP response XML as a Hash" do
94
+ subject.hash.should == probe_full_hash
95
+ end
96
+ end
97
+
98
+ describe "#to_xml" do
99
+ it "should return the raw SOAP response body" do
100
+ subject.to_xml.should == probe_response
101
+ end
102
+ end
103
+
104
+ describe "#doc" do
105
+ it "returns a Nokogiri::XML::Document for the SOAP response XML" do
106
+ subject.doc.should be_a(Nokogiri::XML::Document)
107
+ end
108
+ end
109
+
110
+ describe "#xpath" do
111
+ it "permits XPath access to elements in the request" do
112
+ subject.xpath("//a:Address").first.inner_text.
113
+ should == "urn:uuid:0b679890-fc54-14ba-d428-f73b3e7c2400"
114
+ subject.xpath("//d:ProbeMatch/d:XAddrs").first.inner_text.
115
+ should == "http://10.221.222.74/onvif/device_service"
116
+ end
117
+ end
118
+ end
@@ -0,0 +1,85 @@
1
+ require 'spec_helper'
2
+ require 'ws_discovery/searcher'
3
+
4
+ describe WSDiscovery::Searcher do
5
+ let(:default_probe) do
6
+ "<s:Envelope xmlns:a=\"http://schemas.xmlsoap.org/ws/2004/08/addressing\" " +
7
+ "xmlns:d=\"http://schemas.xmlsoap.org/ws/2005/04/discovery\" xmlns:s=\"h" +
8
+ "ttp://www.w3.org/2003/05/soap-envelope\"><s:Header><a:Action>http://sch" +
9
+ "emas.xmlsoap.org/ws/2005/04/discovery/Probe</a:Action><a:MessageID>uuid" +
10
+ ":a-uuid</a:MessageID><a:To>urn:schemas-xmlsoap-org:ws:2005:04:discovery" +
11
+ "</a:To></s:Header><s:Body><d:Types/><d:Scopes/></s:Body></s:Envelope>"
12
+ end
13
+
14
+ around(:each) do |example|
15
+ EM.run do
16
+ example.run
17
+ EM.stop
18
+ end
19
+ end
20
+
21
+ before do
22
+ WSDiscovery::Searcher.log = false
23
+ WSDiscovery::MulticastConnection.any_instance.stub(:setup_multicast_socket)
24
+ UUID.stub(:generate).and_return('a-uuid')
25
+ end
26
+
27
+ subject do
28
+ WSDiscovery::Searcher.new(1)
29
+ end
30
+
31
+ describe "#initialize" do
32
+ it "does a #probe" do
33
+ WSDiscovery::Searcher.any_instance.should_receive(:probe)
34
+
35
+ subject
36
+ end
37
+ end
38
+
39
+ describe "#receive_data" do
40
+ let(:parsed_response) do
41
+ double 'parsed response'
42
+ end
43
+
44
+ it "takes a response and adds it to the list of responses" do
45
+ response = double 'response'
46
+ subject.stub(:peer_info).and_return(['0.0.0.0', 4567])
47
+
48
+ subject.should_receive(:parse).with(response).exactly(1).times.
49
+ and_return(parsed_response)
50
+ subject.instance_variable_get(:@discovery_responses).should_receive(:<<).
51
+ with(parsed_response)
52
+
53
+ subject.receive_data(response)
54
+ end
55
+ end
56
+
57
+ describe "#parse" do
58
+ before do
59
+ WSDiscovery::MulticastConnection.any_instance.stub(:setup_multicast_socket)
60
+ end
61
+
62
+ it "turns probe matches into WSDiscovery::Responses" do
63
+ result = subject.parse "<Envelope />"
64
+ result.should be_a WSDiscovery::Response
65
+ end
66
+ end
67
+
68
+ describe "#post_init" do
69
+ before { WSDiscovery::Searcher.any_instance.stub(:m_search).and_return("hi") }
70
+
71
+ it "sends a probe as a datagram over 239.255.255.250:3702" do
72
+ subject.should_receive(:send_datagram).
73
+ with(default_probe, '239.255.255.250', 3702).
74
+ and_return 0
75
+ subject.post_init
76
+ end
77
+ end
78
+
79
+ describe "#probe" do
80
+ it "builds the MSEARCH string using the given parameters" do
81
+ subject.probe.should == default_probe
82
+ end
83
+ end
84
+ end
85
+
@@ -0,0 +1,43 @@
1
+ require 'spec_helper'
2
+ require 'ws_discovery'
3
+
4
+ describe WSDiscovery do
5
+ subject { WSDiscovery }
6
+
7
+ describe '.search' do
8
+ let(:multicast_searcher) do
9
+ searcher = double "WSDiscovery::Searcher"
10
+ searcher.stub_chain(:discovery_responses, :subscribe).and_yield(%w[one two])
11
+
12
+ searcher
13
+ end
14
+
15
+ before do
16
+ EM.stub(:run).and_yield
17
+ EM.stub(:add_timer)
18
+ EM.stub(:open_datagram_socket).and_return multicast_searcher
19
+ end
20
+
21
+ context "reactor is already running" do
22
+ it "returns a WSDiscovery::Searcher" do
23
+ EM.stub(:reactor_running?).and_return true
24
+ subject.search.should == multicast_searcher
25
+ end
26
+ end
27
+
28
+ context "reactor is not already running" do
29
+ it "returns an Array of responses" do
30
+ EM.stub(:add_shutdown_hook).and_yield
31
+ subject.search.should == %w[one two]
32
+ end
33
+
34
+ it "opens a UDP socket on '0.0.0.0', port 0" do
35
+ EM.stub(:add_shutdown_hook)
36
+ EM.should_receive(:open_datagram_socket).with('0.0.0.0', 0,
37
+ WSDiscovery::Searcher, {})
38
+ subject.search
39
+ end
40
+ end
41
+ end
42
+ end
43
+
@@ -0,0 +1,32 @@
1
+ $:.push File.expand_path("../lib", __FILE__)
2
+ require 'ws_discovery/version'
3
+
4
+ Gem::Specification.new do |s|
5
+ s.name = "ws_discovery"
6
+ s.version = WSDiscovery::VERSION
7
+ s.homepage = "https://github.com/pelco-automation/ws-discovery"
8
+ s.author = "tindron"
9
+ s.email = "rstoller@gmail.com"
10
+ s.description = "Perform a multicast search for devices using WS-Discovery"
11
+ s.summary = "Search for devices using WS-Discovery"
12
+
13
+ s.required_rubygems_version = ">=1.8.0"
14
+ s.required_ruby_version = Gem::Requirement.new(">= 1.9.3")
15
+ s.files = Dir.glob("{lib,spec}/**/*") + Dir.glob("*.rdoc") +
16
+ %w(Gemfile ws_discovery.gemspec Rakefile)
17
+ s.require_paths = ["lib"]
18
+
19
+ s.add_dependency("builder")
20
+ s.add_dependency("eventmachine")
21
+ s.add_dependency("log_switch", ">=0.1.4")
22
+ s.add_dependency("nokogiri")
23
+ s.add_dependency("nori")
24
+ s.add_dependency("uuid")
25
+
26
+ s.add_development_dependency("bundler", ">= 1.0.21")
27
+ s.add_development_dependency("rake", ">= 0")
28
+ s.add_development_dependency("rspec", "~> 2.6")
29
+ s.add_development_dependency("simplecov", ">= 0")
30
+ s.add_development_dependency("simplecov-rcov", ">= 0")
31
+ s.add_development_dependency("yard", ">= 0.7.2")
32
+ end