easy_upnp 1.1.2 → 1.1.4

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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: a269aa109f5d07c0b8ddfd218316a42073704783
4
- data.tar.gz: ada5f6562fa9b61599348acd514ddca7c5eb4204
3
+ metadata.gz: 77ca5dc016b9e9587ab894416d38ec9ed66f22dd
4
+ data.tar.gz: 2990a6748c83422a25b915cf6bd62d6f62f93507
5
5
  SHA512:
6
- metadata.gz: fbe22254daada0ff4c6bfc9fe3ff8f4a0a61b62345bc3d959fff778e4df452d53c4980495a5a26eff8506d819ab03b9814f0f7503cd0360ae542948a6ae7873e
7
- data.tar.gz: bb77cd15ac6cad082c69986b19cb9d392e322e8405ee9f111eb8744677313565b5832dbeaf1e509ce363ee5490ece40a01a8cb51b2a547316072a535e77dc5d2
6
+ metadata.gz: c449b3c3f8b66bb55d6ba755b1e684b2388ce0be5e663b9594ba7c9ecd255c8b7fa0da5d293c80a8d103a63bdee6b203b773d5edbe00b7fcbce782da3c50fd3e
7
+ data.tar.gz: ea9a9a024ea173a111915249ffb3a4c8a331b0c6f852c69212cd8c9369572e527a4d02465e66c9325788588078180da4b90088e3de584f96c0ab152831197116
data/README.md CHANGED
@@ -132,3 +132,101 @@ validator = client.arg_validator(:SetVolume, :Channel)
132
132
  validator.allowed_values
133
133
  #=> ["Master"]
134
134
  ```
135
+
136
+ ## Events
137
+
138
+ easy_upnp allows you to subscribe to events. UPnP events are supported by registering HTTP callbacks with services. You can read more about the specifics in Section 4 of the [UPnP Device Architecture document](http://upnp.org/specs/arch/UPnP-arch-DeviceArchitecture-v1.1.pdf). Using this you could, for example, receive events when the volume or mute state changes on your UPnP-enabled TV. You might see something like this HTTP request, for example:
139
+
140
+ ```
141
+ NOTIFY / HTTP/1.1
142
+ Host: 192.168.1.100:8888
143
+ Date: Sun, 17 Apr 2016 07:40:01 GMT
144
+ User-Agent: UPnP/1.0
145
+ Content-Type: text/xml; charset="utf-8"
146
+ Content-Length: 479
147
+ NT: upnp:event
148
+ NTS: upnp:propchange
149
+ SID: uuid:9742fed0-046f-11e6-8000-fcf1524b4f9c
150
+ SEQ: 0
151
+
152
+ <?xml version="1.0"?><e:propertyset xmlns:e="urn:schemas-upnp-org:event-1-0"><e:property><LastChange>&lt;Event xmlns=&quot;urn:schemas-upnp-org:metadata-1-0/RCS/&quot;&gt;
153
+ &lt;InstanceID val=&quot;0&quot;&gt;
154
+ &lt;PresetNameList val=&quot;FactoryDefaults&quot;/&gt;
155
+ &lt;Mute val=&quot;0&quot; channel=&quot;Master&quot;/&gt;
156
+ &lt;Volume val=&quot;34&quot; channel=&quot;Master&quot;/&gt;
157
+ &lt;/InstanceID&gt;
158
+ &lt;/Event&gt;
159
+ </LastChange></e:property></e:propertyset>
160
+ ```
161
+
162
+ There are two ways you can subscribe to events with easy_upnp:
163
+
164
+ 1. Registering a custom HTTP endpoint.
165
+ 2. Providing a callback `lambda` or `Proc` which is called each time an event is fired.
166
+
167
+ In the case of (2), easy_upnp behind the scenes starts a WEBrick HTTP server, which calls the provided callback whenever it receives an HTTP `NOTIFY` request.
168
+
169
+ Because event subscriptions expire, easy_upnp starts a background thread to renew the subscription on an interval.
170
+
171
+ #### Calling URLs
172
+
173
+ To add a URL to be called on events:
174
+
175
+ ```ruby
176
+ # Registers the provided URL with the service. If everything works appropriately, this
177
+ # URL will be called with HTTP NOTIFY requests from the service.
178
+ manager = service.add_event_callback('http://myserver/path/to/callback')
179
+
180
+ # The object that's returned allows you to manage the event subscription. To
181
+ # cancel the subscription, for example:
182
+ manager.unsubscribe
183
+
184
+ # You can also start the subscription after unsubscribing:
185
+ manager.subscribe
186
+
187
+ # Or get the subscription identifier:
188
+ manager.subscription_id
189
+ #=> "uuid:6ef254f0-04d1-11e6-8000-fcf1524b4f9c"
190
+ ```
191
+
192
+ You can also construct a manager that attempts to manage an existing subscription:
193
+
194
+ ```ruby
195
+ manager = service.add_event_callback('http://myserver/path/to/callback') do |c|
196
+ c.existing_sid = 'uuid:6ef254f0-04d1-11e6-8000-fcf1524b4f9c'
197
+ end
198
+ ```
199
+
200
+ #### Calling ruby code
201
+
202
+ If you don't want to have to set up an HTTP endpoint to listen to events, you can have easy_upnp do it for you. The `on_event` starts an internal HTTP server on an ephemeral port behind the scenes and triggers the provided callback each time a request is recieved.
203
+
204
+ ```ruby
205
+ # Parse and print the XML body of the request
206
+ callback = ->(request) { puts Nokogiri::XML(request.body).to_xml }
207
+ manager = service.on_event(callback)
208
+
209
+ # End the subscription and shut down the internal HTTP server
210
+ manager.unsubscribe
211
+
212
+ # This will start a new HTTP server and start a new subscription
213
+ manager.subscribe
214
+ ```
215
+
216
+ While the default configurations are probably fine for most situations, you can configure both the internal HTTP server and the subscription manager when you call `on_event` by passing a configuration block:
217
+
218
+ ```ruby
219
+ manager = service.on_event(callback) do |c|
220
+ c.configure_http_listener do |l|
221
+ l.listen_port = 8888
222
+ l.bind_address = '192.168.1.100'
223
+ end
224
+
225
+ c.configure_subscription_manager do |m|
226
+ m.requested_timeout = 1800
227
+ m.resubscription_interval_buffer = 60
228
+ m.existing_sid = 'uuid:6ef254f0-04d1-11e6-8000-fcf1524b4f9c'
229
+ m.log_level = Logger::INFO
230
+ end
231
+ end
232
+ ```
@@ -1,11 +1,13 @@
1
+ require_relative '../options_base'
2
+
1
3
  module EasyUpnp
2
4
  class ClientWrapper
3
5
  def initialize(endpoint,
4
6
  urn,
5
- call_options:,
6
- advanced_typecasting:,
7
- log_enabled:,
8
- log_level:)
7
+ call_options,
8
+ advanced_typecasting,
9
+ log_enabled,
10
+ log_level)
9
11
 
10
12
  # For some reason was not able to pass these options in the config block
11
13
  # in Savon 2.11
@@ -40,9 +42,10 @@ module EasyUpnp
40
42
  :'xmlns:u' => @urn
41
43
  },
42
44
  }.merge(@call_options)
45
+ advanced_typecasting = @advanced_typecasting
43
46
 
44
47
  response = @client.call(action_name, attrs) do
45
- advanced_typecasting @advanced_typecasting
48
+ advanced_typecasting advanced_typecasting
46
49
  message(args)
47
50
  end
48
51
  end
@@ -53,10 +53,10 @@ module EasyUpnp
53
53
  @client = ClientWrapper.new(
54
54
  service_endpoint,
55
55
  urn,
56
- call_options: @options.call_options,
57
- advanced_typecasting: @options.advanced_typecasting,
58
- log_enabled: @options.log_enabled,
59
- log_level: @options.log_level
56
+ @options.call_options,
57
+ @options.advanced_typecasting,
58
+ @options.log_enabled,
59
+ @options.log_level
60
60
  )
61
61
 
62
62
  definition_xml = Nokogiri::XML(definition)
@@ -163,8 +163,17 @@ module EasyUpnp
163
163
 
164
164
  options = EventConfigOptions.new(&block)
165
165
 
166
- listener = EasyUpnp::HttpListener.new(callback: callback) do |c|
166
+ listener = EasyUpnp::HttpListener.new do |c|
167
167
  options.configure_http_listener.call(c)
168
+
169
+ # It'd be kinda weird if a user set this (since a callback is taken as
170
+ # an argument to the `on_event` method), but it'd be even weirder if
171
+ # we ignored it.
172
+ user_callback = c.callback
173
+ c.callback do |r|
174
+ user_callback.call(r) if user_callback
175
+ callback.call(r)
176
+ end
168
177
  end
169
178
 
170
179
  # exposing the URL as a lambda allows the subscription manager to get a
@@ -1,3 +1,3 @@
1
1
  module EasyUpnp
2
- VERSION = '1.1.2'
2
+ VERSION = '1.1.4'
3
3
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: easy_upnp
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.1.2
4
+ version: 1.1.4
5
5
  platform: ruby
6
6
  authors:
7
7
  - Christopher Mullins
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2016-04-17 00:00:00.000000000 Z
11
+ date: 2016-04-18 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rake