wemote 0.1.0 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: e8691a6386c98200751335860a3601d8377df98a
4
- data.tar.gz: c24270bd139e1065b1a7e2e33695629241397bc1
3
+ metadata.gz: b18903132febc3de01e2796ce0b7adde752b030f
4
+ data.tar.gz: 07503eba981f501449f2b6f86afb90baca0ad7c7
5
5
  SHA512:
6
- metadata.gz: ae867770e792ab4ab14a25147a94f8f18bd5ebd4297cdce837bc78c41bc286dc20d11dd24267336680001fecddf2822ab8dc03d74f3ab431b8b57d792c65a1e9
7
- data.tar.gz: 3f9008db4572c37f11c4fd0a6082e55afae6a827fb82cb6250eb27fb0351a447d464de2424ccadcb9a65a24d2b0c2471449fac515546ab3931f5892f7e19774c
6
+ metadata.gz: 3313aa5e43f3394d505f9a2b6c7dbfe06dc6f49effaaea8b86e43542e93f5cb4583793631b34cd6fac99be1aa3440e4ca3b9b40320a8d4ba36fea52418e1662a
7
+ data.tar.gz: ad62e4b4497c8509246861e52479b677ce495d1859103fbd67823552af6b92f346ad7972cd1dbc8f54e1b7129aa52429172691be75eb2331e639bd09e879b237
@@ -0,0 +1 @@
1
+ service_name: travis-ci
@@ -1,3 +1,8 @@
1
1
  language: ruby
2
2
  rvm:
3
+ - 2.1.0
4
+ - 2.0.0
5
+ - 1.9.3
6
+ - rbx
7
+ - ruby-head
3
8
  - jruby-head
data/Gemfile CHANGED
@@ -1,9 +1,10 @@
1
1
  source 'https://rubygems.org'
2
-
3
- # Specify your gem's dependencies in manticore.gemspec
4
2
  gemspec
5
3
 
6
- gem 'coveralls', require: false
7
- gem 'manticore', git: 'git://github.com/cheald/manticore.git'
4
+ # Commented out until I can determine a way to set engine-specific dependencies
5
+ # gem 'manticore', git: 'git://github.com/cheald/manticore.git'
6
+ #gem 'typhoeus'
7
+ gem 'coveralls', :require => false
8
+ gem 'httparty'
8
9
  gem 'rspec'
9
10
  gem 'rake'
data/README.md CHANGED
@@ -1,20 +1,20 @@
1
- # Wemote [![Build Status](https://travis-ci.org/gisikw/wemote.png)](https://travis-ci.org/gisikw/wemote)[![Coverage Status](https://coveralls.io/repos/gisikw/wemote/badge.png)](https://coveralls.io/r/gisikw/wemote)
1
+ # Wemote [![Build Status](https://travis-ci.org/gisikw/wemote.png)](https://travis-ci.org/gisikw/wemote) [![Gem Version](https://badge.fury.io/rb/wemote.png)](http://badge.fury.io/rb/wemote) [![Coverage Status](https://coveralls.io/repos/gisikw/wemote/badge.png)](https://coveralls.io/r/gisikw/wemote) [![Code Climate](https://codeclimate.com/github/gisikw/wemote.png)](https://codeclimate.com/github/gisikw/wemote)
2
2
 
3
- Wemote is an interface for controlling WeMo light switches (and possibly outlets in the future). Unlike other implementations, it does not rely upon `playful` for upnp discovery, which makes it compatible with JRuby. For the moment, Wemote leverages Manticore for its HTTP requests, and until that is abstracted, this library is only compatible with JRuby.
3
+ Wemote is an interface for controlling WeMo light switches (and possibly outlets in the future). Unlike other implementations, it does not rely upon `playful` for upnp discovery, which makes it compatible with alternative Ruby engines, such as JRuby.
4
4
 
5
5
  ## Installation
6
6
 
7
- First, clone the repository:
7
+ Add this line to your application's Gemfile:
8
8
 
9
- git clone https://github.com/gisikw/wemote.git
9
+ gem 'wemote'
10
10
 
11
11
  And then execute:
12
12
 
13
- $ gem build wemote.gemspec
13
+ $ bundle
14
14
 
15
- Finally, run:
15
+ Or install it yourself as:
16
16
 
17
- $ gem install wemote-0.0.1.gem
17
+ $ gem install wemote
18
18
 
19
19
  ## Usage
20
20
 
@@ -32,7 +32,7 @@ switch = Wemote::Switch.find('Kitchen Switch') #=> #<Remo::Switch:0x27f33aef @ho
32
32
 
33
33
  Given a Switch instance, you can call the following methods:
34
34
  ```ruby
35
- switch.state #=> ["off","on"]
35
+ switch.get_state #=> [:off,:on]
36
36
  switch.off? #=> [true,false]
37
37
  switch.on? #=> [true,false]
38
38
  switch.on!
@@ -40,6 +40,10 @@ switch.off!
40
40
  switch.toggle!
41
41
  ```
42
42
 
43
+ ## Performance
44
+
45
+ Wemote is designed to be performant - and as such, it will leverage the best HTTP library available for making requests. Currently, Wemote will use (in order of preference): `manticore`, `typhoeus`, `httparty`, and finally (miserably) `net/http`. Because you probably like things fast too, we recommend you `gem install manticore` on JRuby, or `gem install typhoeus` on another engine. In order to keep the gem as flexible as possible, none of these are direct dependencies. They just make Wemote happy and fast.
46
+
43
47
  ## Contributing
44
48
 
45
49
  1. Fork it
@@ -1,7 +1,7 @@
1
- require 'manticore'
2
1
  require_relative './wemote/version'
3
2
 
4
3
  module Wemote
5
4
  require_relative './wemote/switch'
5
+ require_relative './wemote/client'
6
6
  require_relative './wemote/xml'
7
7
  end
@@ -0,0 +1,92 @@
1
+ module Wemote
2
+ class Client
3
+
4
+ def self.technique
5
+ @technique ||= begin
6
+ constants.collect {|const_name| const_get(const_name)}.select {|const| const.class == Module}.detect do |mod|
7
+ fulfilled = false
8
+ begin
9
+ mod.const_get(:DEPENDENCIES).map{|d|require d}
10
+ fulfilled = true
11
+ rescue LoadError
12
+ end
13
+ fulfilled
14
+ end
15
+ end
16
+ end
17
+
18
+ module Manticore
19
+ DEPENDENCIES = ['manticore']
20
+
21
+ def get(*args)
22
+ _get(::Manticore,*args).call
23
+ end
24
+
25
+ def post(*args)
26
+ _post(::Manticore,*args).call
27
+ end
28
+
29
+ end
30
+
31
+ module Typhoeus
32
+ DEPENDENCIES = ['typhoeus']
33
+
34
+ def get(*args)
35
+ _get(::Typhoeus,*args)
36
+ end
37
+
38
+ def post(*args)
39
+ _post(::Typhoeus,*args)
40
+ end
41
+
42
+ end
43
+
44
+ module HTTParty
45
+ DEPENDENCIES = ['httparty']
46
+
47
+ def get(*args)
48
+ _get(::HTTParty,*args)
49
+ end
50
+
51
+ def post(*args)
52
+ _post(::HTTParty,*args)
53
+ end
54
+ end
55
+
56
+ module NetHTTP
57
+ DEPENDENCIES = ['net/http','uri']
58
+
59
+ def get(url,body=nil,headers=nil)
60
+ uri = URI.parse(url)
61
+ http = Net::HTTP.new(uri.host, uri.port)
62
+ request = Net::HTTP::Get.new(uri.request_uri)
63
+ headers.map{|k,v|request[k]=v} if headers
64
+ response = http.request(request)
65
+ end
66
+
67
+ def post(url,body=nil,headers=nil)
68
+ uri = URI.parse(url)
69
+ http = Net::HTTP.new(uri.host, uri.port)
70
+ request = Net::HTTP::Post.new(uri.request_uri)
71
+ headers.map{|k,v|request[k]=v} if headers
72
+ (request.body = body) if body
73
+ response = http.request(request)
74
+ end
75
+ end
76
+
77
+ def initialize
78
+ extend Wemote::Client.technique
79
+ end
80
+
81
+ private
82
+
83
+ def _get(lib,url,body=nil,headers=nil)
84
+ lib.get(url,{body:body,headers:headers})
85
+ end
86
+
87
+ def _post(lib,url,body=nil,headers=nil)
88
+ lib.post(url,{body:body,headers:headers})
89
+ end
90
+
91
+ end
92
+ end
@@ -37,19 +37,26 @@ EOF
37
37
 
38
38
  private
39
39
 
40
- def fetch_switches
40
+ def ssdp_socket
41
41
  socket = UDPSocket.new
42
- membership = IPAddr.new(MULTICAST_ADDR).hton + IPAddr.new(BIND_ADDR).hton
43
-
44
- socket.setsockopt(Socket::IPPROTO_IP, Socket::IP_ADD_MEMBERSHIP, membership)
42
+ socket.setsockopt(Socket::IPPROTO_IP, Socket::IP_ADD_MEMBERSHIP, IPAddr.new(MULTICAST_ADDR).hton + IPAddr.new(BIND_ADDR).hton)
45
43
  socket.setsockopt(Socket::IPPROTO_IP, Socket::IP_MULTICAST_TTL, 1)
46
44
  socket.setsockopt(Socket::SOL_SOCKET, Socket::SO_REUSEPORT, 1)
47
45
  socket.bind(BIND_ADDR,PORT)
46
+ socket
47
+ end
48
48
 
49
+ def fetch_switches
50
+ socket = ssdp_socket
49
51
  switches = []
50
52
 
51
53
  3.times { socket.send(DISCOVERY, 0, MULTICAST_ADDR, PORT) }
52
54
 
55
+ # The following is a bit silly, but is necessary for JRuby support,
56
+ # which seems to have some issues with socket interruption.
57
+ # If you have a working JRuby solution that doesn't require this
58
+ # kind of hackery, by all means, submit a pull request!
59
+
53
60
  sleep 1
54
61
 
55
62
  parser = Thread.start do
@@ -86,31 +93,30 @@ EOF
86
93
 
87
94
  def get_state
88
95
  response = begin
89
- client.post("http://#{@host}:#{@port}/upnp/control/basicevent1",:body => Wemote::XML.get_binary_state, :headers => GET_HEADERS).call
96
+ client.post("http://#{@host}:#{@port}/upnp/control/basicevent1",Wemote::XML.get_binary_state,GET_HEADERS)
90
97
  rescue Exception
91
- client.post("http://#{@host}:#{@port}/upnp/control/basicevent1",:body => Wemote::XML.get_binary_state, :headers => GET_HEADERS).call
98
+ client.post("http://#{@host}:#{@port}/upnp/control/basicevent1",Wemote::XML.get_binary_state,GET_HEADERS)
92
99
  end
93
100
  response.body.match(/<BinaryState>(\d)<\/BinaryState>/)[1] == '1' ? :on : :off
94
101
  end
95
102
 
96
103
  def set_state(state)
97
104
  begin
98
- client.post("http://#{@host}:#{@port}/upnp/control/basicevent1",:body => Wemote::XML.set_binary_state(state), :headers => SET_HEADERS).call
105
+ client.post("http://#{@host}:#{@port}/upnp/control/basicevent1",Wemote::XML.set_binary_state(state),SET_HEADERS)
99
106
  rescue Exception
100
- client.post("http://#{@host}:#{@port}/upnp/control/basicevent1",:body => Wemote::XML.set_binary_state(state), :headers => SET_HEADERS).call
107
+ client.post("http://#{@host}:#{@port}/upnp/control/basicevent1",Wemote::XML.set_binary_state(state),SET_HEADERS)
101
108
  end
102
109
  end
103
110
 
104
111
  private
105
112
 
106
113
  def client
107
- @client ||= Manticore::Client.new
114
+ @client ||= Wemote::Client.new
108
115
  end
109
116
 
110
117
  def set_meta
111
- client.get("http://#{@host}:#{@port}/setup.xml") do |response|
112
- @name = response.body.match(/<friendlyName>([^<]+)<\/friendlyName>/)[1]
113
- end
118
+ response = client.get("http://#{@host}:#{@port}/setup.xml")
119
+ @name = response.body.match(/<friendlyName>([^<]+)<\/friendlyName>/)[1]
114
120
  end
115
121
 
116
122
  end
@@ -1,3 +1,3 @@
1
1
  module Wemote
2
- VERSION = "0.1.0"
2
+ VERSION = "0.2.0"
3
3
  end
@@ -1,4 +1,4 @@
1
- require 'wemote'
2
1
  require 'coveralls'
3
-
4
2
  Coveralls.wear!
3
+
4
+ require 'wemote'
@@ -9,8 +9,8 @@ describe Wemote::Switch do
9
9
 
10
10
  describe '.find' do
11
11
  it 'should return an instance whose name matches the argument' do
12
- client = Manticore::Client.new
13
- client.stub('http://fakehost:1234/setup.xml',body:'<friendlyName>Test Switch</friendlyName>',code:200)
12
+ client = Wemote::Client.new
13
+ client.stub(:get).and_return(double('response',{body:'<friendlyName>Test Switch</friendlyName>'}))
14
14
  Wemote::Switch.any_instance.stub(:client).and_return(client)
15
15
  switch = Wemote::Switch.new('fakehost','1234')
16
16
  Wemote::Switch.instance_variable_set(:@switches,[switch])
@@ -22,8 +22,8 @@ describe Wemote::Switch do
22
22
 
23
23
  describe 'instance methods' do
24
24
  before do
25
- client = Manticore::Client.new
26
- client.stub('http://fakehost:1234/setup.xml',body:'<friendlyName>Test Switch</friendlyName>',code:200)
25
+ client = Wemote::Client.new
26
+ client.stub(:get).and_return(double('response',body:'<friendlyName>Test Switch</friendlyName>'))
27
27
  Wemote::Switch.any_instance.stub(:client).and_return(client)
28
28
  @switch = Wemote::Switch.new('fakehost','1234')
29
29
  end
@@ -74,16 +74,17 @@ describe Wemote::Switch do
74
74
 
75
75
  describe 'get_state' do
76
76
  it 'should return the binary state of the switch' do
77
- @switch.client.stub('http://fakehost:1234/upnp/control/basicevent1',body:'<BinaryState>1</BinaryState>',code:200)
77
+
78
+ @switch.client.stub(:post).and_return(double('response',body:'<BinaryState>1</BinaryState>'))
78
79
  @switch.get_state.should == :on
79
- @switch.client.stub('http://fakehost:1234/upnp/control/basicevent1',body:'<BinaryState>0</BinaryState>',code:200)
80
+ @switch.client.stub(:post).and_return(double('response',body:'<BinaryState>0</BinaryState>'))
80
81
  @switch.get_state.should == :off
81
82
  end
82
83
  end
83
84
 
84
85
  describe 'set_state' do
85
86
  it 'should set the binary state of the switch' do
86
- @switch.client.stub('http://fakehost:1234/upnp/control/basicevent1',body:'Called',code:200)
87
+ @switch.client.stub(:post).and_return(double('response',body:'Called'))
87
88
  @switch.set_state(1).body.should == 'Called'
88
89
  end
89
90
  end
@@ -8,8 +8,8 @@ Gem::Specification.new do |spec|
8
8
  spec.version = Wemote::VERSION
9
9
  spec.authors = ["Kevin Gisi"]
10
10
  spec.email = ["kevin@kevingisi.com"]
11
- spec.description = %q{Wemote is a JRuby-friendly API for Wemo light switches}
12
- spec.summary = %q{Wemote is a JRuby-friendly API for Wemo light switches}
11
+ spec.description = %q{Wemote is a Ruby-agnostic gem for Wemo light switches}
12
+ spec.summary = %q{Wemote is a Ruby-agnostic gem for Wemo light switches}
13
13
  spec.homepage = "https://github.com/gisikw/wemote"
14
14
  spec.license = "MIT"
15
15
  spec.platform = 'ruby'
@@ -18,6 +18,4 @@ Gem::Specification.new do |spec|
18
18
  spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
19
19
  spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
20
20
  spec.require_paths = ["lib"]
21
-
22
- spec.add_dependency "manticore", "~> 0.2.1"
23
21
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: wemote
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 0.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Kevin Gisi
@@ -9,28 +9,15 @@ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
11
  date: 2014-03-06 00:00:00.000000000 Z
12
- dependencies:
13
- - !ruby/object:Gem::Dependency
14
- name: manticore
15
- version_requirements: !ruby/object:Gem::Requirement
16
- requirements:
17
- - - ~>
18
- - !ruby/object:Gem::Version
19
- version: 0.2.1
20
- requirement: !ruby/object:Gem::Requirement
21
- requirements:
22
- - - ~>
23
- - !ruby/object:Gem::Version
24
- version: 0.2.1
25
- prerelease: false
26
- type: :runtime
27
- description: Wemote is a JRuby-friendly API for Wemo light switches
12
+ dependencies: []
13
+ description: Wemote is a Ruby-agnostic gem for Wemo light switches
28
14
  email:
29
15
  - kevin@kevingisi.com
30
16
  executables: []
31
17
  extensions: []
32
18
  extra_rdoc_files: []
33
19
  files:
20
+ - .coveralls.yml
34
21
  - .gitignore
35
22
  - .travis.yml
36
23
  - Gemfile
@@ -38,6 +25,7 @@ files:
38
25
  - README.md
39
26
  - Rakefile
40
27
  - lib/wemote.rb
28
+ - lib/wemote/client.rb
41
29
  - lib/wemote/switch.rb
42
30
  - lib/wemote/version.rb
43
31
  - lib/wemote/xml.rb
@@ -69,7 +57,7 @@ rubyforge_project:
69
57
  rubygems_version: 2.2.2
70
58
  signing_key:
71
59
  specification_version: 4
72
- summary: Wemote is a JRuby-friendly API for Wemo light switches
60
+ summary: Wemote is a Ruby-agnostic gem for Wemo light switches
73
61
  test_files:
74
62
  - spec/spec_helper.rb
75
63
  - spec/wemote/switch_spec.rb