shingara-blather 0.4.8
Sign up to get free protection for your applications and to get access to all the features.
- data/LICENSE +22 -0
- data/README.md +162 -0
- data/examples/echo.rb +18 -0
- data/examples/execute.rb +16 -0
- data/examples/ping_pong.rb +37 -0
- data/examples/print_hierarchy.rb +76 -0
- data/examples/rosterprint.rb +14 -0
- data/examples/stream_only.rb +27 -0
- data/examples/xmpp4r/echo.rb +35 -0
- data/lib/blather/client/client.rb +310 -0
- data/lib/blather/client/dsl/pubsub.rb +170 -0
- data/lib/blather/client/dsl.rb +264 -0
- data/lib/blather/client.rb +87 -0
- data/lib/blather/core_ext/nokogiri.rb +40 -0
- data/lib/blather/errors/sasl_error.rb +43 -0
- data/lib/blather/errors/stanza_error.rb +107 -0
- data/lib/blather/errors/stream_error.rb +82 -0
- data/lib/blather/errors.rb +69 -0
- data/lib/blather/jid.rb +142 -0
- data/lib/blather/roster.rb +111 -0
- data/lib/blather/roster_item.rb +122 -0
- data/lib/blather/stanza/disco/disco_info.rb +176 -0
- data/lib/blather/stanza/disco/disco_items.rb +132 -0
- data/lib/blather/stanza/disco.rb +25 -0
- data/lib/blather/stanza/iq/query.rb +53 -0
- data/lib/blather/stanza/iq/roster.rb +179 -0
- data/lib/blather/stanza/iq.rb +138 -0
- data/lib/blather/stanza/message.rb +332 -0
- data/lib/blather/stanza/presence/status.rb +212 -0
- data/lib/blather/stanza/presence/subscription.rb +101 -0
- data/lib/blather/stanza/presence.rb +163 -0
- data/lib/blather/stanza/pubsub/affiliations.rb +79 -0
- data/lib/blather/stanza/pubsub/create.rb +65 -0
- data/lib/blather/stanza/pubsub/errors.rb +18 -0
- data/lib/blather/stanza/pubsub/event.rb +123 -0
- data/lib/blather/stanza/pubsub/items.rb +103 -0
- data/lib/blather/stanza/pubsub/publish.rb +103 -0
- data/lib/blather/stanza/pubsub/retract.rb +92 -0
- data/lib/blather/stanza/pubsub/subscribe.rb +68 -0
- data/lib/blather/stanza/pubsub/subscription.rb +134 -0
- data/lib/blather/stanza/pubsub/subscriptions.rb +81 -0
- data/lib/blather/stanza/pubsub/unsubscribe.rb +68 -0
- data/lib/blather/stanza/pubsub.rb +129 -0
- data/lib/blather/stanza/pubsub_owner/delete.rb +52 -0
- data/lib/blather/stanza/pubsub_owner/purge.rb +52 -0
- data/lib/blather/stanza/pubsub_owner.rb +51 -0
- data/lib/blather/stanza.rb +149 -0
- data/lib/blather/stream/client.rb +31 -0
- data/lib/blather/stream/component.rb +38 -0
- data/lib/blather/stream/features/resource.rb +63 -0
- data/lib/blather/stream/features/sasl.rb +187 -0
- data/lib/blather/stream/features/session.rb +44 -0
- data/lib/blather/stream/features/tls.rb +28 -0
- data/lib/blather/stream/features.rb +53 -0
- data/lib/blather/stream/parser.rb +102 -0
- data/lib/blather/stream.rb +231 -0
- data/lib/blather/xmpp_node.rb +218 -0
- data/lib/blather.rb +78 -0
- data/spec/blather/client/client_spec.rb +559 -0
- data/spec/blather/client/dsl/pubsub_spec.rb +462 -0
- data/spec/blather/client/dsl_spec.rb +143 -0
- data/spec/blather/core_ext/nokogiri_spec.rb +83 -0
- data/spec/blather/errors/sasl_error_spec.rb +33 -0
- data/spec/blather/errors/stanza_error_spec.rb +129 -0
- data/spec/blather/errors/stream_error_spec.rb +108 -0
- data/spec/blather/errors_spec.rb +33 -0
- data/spec/blather/jid_spec.rb +87 -0
- data/spec/blather/roster_item_spec.rb +96 -0
- data/spec/blather/roster_spec.rb +103 -0
- data/spec/blather/stanza/discos/disco_info_spec.rb +226 -0
- data/spec/blather/stanza/discos/disco_items_spec.rb +148 -0
- data/spec/blather/stanza/iq/query_spec.rb +64 -0
- data/spec/blather/stanza/iq/roster_spec.rb +140 -0
- data/spec/blather/stanza/iq_spec.rb +45 -0
- data/spec/blather/stanza/message_spec.rb +132 -0
- data/spec/blather/stanza/presence/status_spec.rb +132 -0
- data/spec/blather/stanza/presence/subscription_spec.rb +105 -0
- data/spec/blather/stanza/presence_spec.rb +66 -0
- data/spec/blather/stanza/pubsub/affiliations_spec.rb +57 -0
- data/spec/blather/stanza/pubsub/create_spec.rb +56 -0
- data/spec/blather/stanza/pubsub/event_spec.rb +84 -0
- data/spec/blather/stanza/pubsub/items_spec.rb +79 -0
- data/spec/blather/stanza/pubsub/publish_spec.rb +83 -0
- data/spec/blather/stanza/pubsub/retract_spec.rb +75 -0
- data/spec/blather/stanza/pubsub/subscribe_spec.rb +61 -0
- data/spec/blather/stanza/pubsub/subscription_spec.rb +97 -0
- data/spec/blather/stanza/pubsub/subscriptions_spec.rb +59 -0
- data/spec/blather/stanza/pubsub/unsubscribe_spec.rb +61 -0
- data/spec/blather/stanza/pubsub_owner/delete_spec.rb +50 -0
- data/spec/blather/stanza/pubsub_owner/purge_spec.rb +50 -0
- data/spec/blather/stanza/pubsub_owner_spec.rb +27 -0
- data/spec/blather/stanza/pubsub_spec.rb +67 -0
- data/spec/blather/stanza_spec.rb +116 -0
- data/spec/blather/stream/client_spec.rb +1011 -0
- data/spec/blather/stream/component_spec.rb +95 -0
- data/spec/blather/stream/parser_spec.rb +145 -0
- data/spec/blather/xmpp_node_spec.rb +231 -0
- data/spec/fixtures/pubsub.rb +311 -0
- data/spec/spec_helper.rb +43 -0
- metadata +249 -0
@@ -0,0 +1,310 @@
|
|
1
|
+
require File.join(File.dirname(__FILE__), *%w[.. .. blather])
|
2
|
+
|
3
|
+
module Blather
|
4
|
+
# # Blather Client
|
5
|
+
#
|
6
|
+
# Blather's Client class provides a set of helpers for working with common
|
7
|
+
# XMPP tasks such as setting up and starting the connection, settings
|
8
|
+
# status, registering and dispatching filters and handlers and roster
|
9
|
+
# management.
|
10
|
+
#
|
11
|
+
# Client can be used separately from the DSL if you'd like to implement your
|
12
|
+
# own DSL Here's the echo example using the client without the DSL:
|
13
|
+
#
|
14
|
+
# require 'blather/client/client'
|
15
|
+
# client = Client.setup 'echo@jabber.local', 'echo'
|
16
|
+
#
|
17
|
+
# client.register_handler(:ready) do
|
18
|
+
# puts "Connected ! send messages to #{client.jid.stripped}."
|
19
|
+
# end
|
20
|
+
#
|
21
|
+
# client.register_handler :subscription, :request? do |s|
|
22
|
+
# client.write s.approve!
|
23
|
+
# end
|
24
|
+
#
|
25
|
+
# client.register_handler :message, :chat?, :body => 'exit' do |m|
|
26
|
+
# client.write Blather::Stanza::Message.new(m.from, 'Exiting...')
|
27
|
+
# client.close
|
28
|
+
# end
|
29
|
+
#
|
30
|
+
# client.register_handler :message, :chat?, :body do |m|
|
31
|
+
# client.write Blather::Stanza::Message.new(m.from, "You sent: #{m.body}")
|
32
|
+
# end
|
33
|
+
#
|
34
|
+
class Client
|
35
|
+
attr_reader :jid,
|
36
|
+
:roster
|
37
|
+
|
38
|
+
# Create a new client and set it up
|
39
|
+
#
|
40
|
+
# @param [Blather::JID, #to_s] jid the JID to authorize with
|
41
|
+
# @param [String] password the password to authorize with
|
42
|
+
# @param [String] host if this isn't set it'll be resolved off the JID's
|
43
|
+
# domain
|
44
|
+
# @param [Fixnum, String] port the port to connect to.
|
45
|
+
#
|
46
|
+
# @return [Blather::Client]
|
47
|
+
def self.setup(jid, password, host = nil, port = nil)
|
48
|
+
self.new.setup(jid, password, host, port)
|
49
|
+
end
|
50
|
+
|
51
|
+
def initialize # @private
|
52
|
+
@state = :initializing
|
53
|
+
|
54
|
+
@status = Stanza::Presence::Status.new
|
55
|
+
@handlers = {}
|
56
|
+
@tmp_handlers = {}
|
57
|
+
@filters = {:before => [], :after => []}
|
58
|
+
@roster = Roster.new self
|
59
|
+
|
60
|
+
setup_initial_handlers
|
61
|
+
end
|
62
|
+
|
63
|
+
# Get the current status. Taken from the `state` attribute of Status
|
64
|
+
def status
|
65
|
+
@status.state
|
66
|
+
end
|
67
|
+
|
68
|
+
# Set the status. Status can be set with either a single value or an array
|
69
|
+
# containing
|
70
|
+
#
|
71
|
+
# [state, message, to].
|
72
|
+
def status=(state)
|
73
|
+
state, msg, to = state
|
74
|
+
|
75
|
+
status = Stanza::Presence::Status.new state, msg
|
76
|
+
status.to = to
|
77
|
+
@status = status unless to
|
78
|
+
|
79
|
+
write status
|
80
|
+
end
|
81
|
+
|
82
|
+
# Start the connection.
|
83
|
+
#
|
84
|
+
# The stream type used is based on the JID. If a node exists it uses
|
85
|
+
# Blather::Stream::Client otherwise Blather::Stream::Component
|
86
|
+
def run
|
87
|
+
raise 'not setup!' unless setup?
|
88
|
+
klass = @setup[0].node ? Blather::Stream::Client : Blather::Stream::Component
|
89
|
+
klass.start self, *@setup
|
90
|
+
end
|
91
|
+
alias_method :connect, :run
|
92
|
+
|
93
|
+
# Register a filter to be run before or after the handler chain is run.
|
94
|
+
#
|
95
|
+
# @param [<:before, :after>] type the filter type
|
96
|
+
# @param [Symbol, nil] handler set the filter on a specific handler
|
97
|
+
# @param [guards] guards take a look at the guards documentation
|
98
|
+
# @yield [Blather::Stanza] stanza the incomming stanza
|
99
|
+
def register_filter(type, handler = nil, *guards, &filter)
|
100
|
+
unless [:before, :after].include?(type)
|
101
|
+
raise "Invalid filter: #{type}. Must be :before or :after"
|
102
|
+
end
|
103
|
+
@filters[type] << [guards, handler, filter]
|
104
|
+
end
|
105
|
+
|
106
|
+
# Register a temporary handler. Temporary handlers are based on the ID of
|
107
|
+
# the JID and live only until a stanza with said ID is received.
|
108
|
+
#
|
109
|
+
# @param [#to_s] id the ID of the stanza that should be handled
|
110
|
+
# @yield [Blather::Stanza] stanza the incomming stanza
|
111
|
+
def register_tmp_handler(id, &handler)
|
112
|
+
@tmp_handlers[id.to_s] = handler
|
113
|
+
end
|
114
|
+
|
115
|
+
# Register a handler
|
116
|
+
#
|
117
|
+
# @param [Symbol, nil] handler set the filter on a specific handler
|
118
|
+
# @param [guards] guards take a look at the guards documentation
|
119
|
+
# @yield [Blather::Stanza] stanza the incomming stanza
|
120
|
+
def register_handler(type, *guards, &handler)
|
121
|
+
check_handler type, guards
|
122
|
+
@handlers[type] ||= []
|
123
|
+
@handlers[type] << [guards, handler]
|
124
|
+
end
|
125
|
+
|
126
|
+
# Write data to the stream
|
127
|
+
#
|
128
|
+
# @param [#to_xml, #to_s] stanza the content to send down the wire
|
129
|
+
def write(stanza)
|
130
|
+
self.stream.send(stanza)
|
131
|
+
end
|
132
|
+
|
133
|
+
# Helper that will create a temporary handler for the stanza being sent
|
134
|
+
# before writing it to the stream.
|
135
|
+
#
|
136
|
+
# client.write_with_handler(stanza) { |s| "handle stanza here" }
|
137
|
+
#
|
138
|
+
# is equivalent to:
|
139
|
+
#
|
140
|
+
# client.register_tmp_handler(stanza.id) { |s| "handle stanza here" }
|
141
|
+
# client.write stanza
|
142
|
+
#
|
143
|
+
# @param [Blather::Stanza] stanza the stanza to send down the wire
|
144
|
+
# @yield [Blather::Stanza] stanza the reply stanza
|
145
|
+
def write_with_handler(stanza, &handler)
|
146
|
+
register_tmp_handler stanza.id, &handler
|
147
|
+
write stanza
|
148
|
+
end
|
149
|
+
|
150
|
+
# Close the connection
|
151
|
+
def close
|
152
|
+
self.stream.close_connection_after_writing
|
153
|
+
end
|
154
|
+
|
155
|
+
def post_init(stream, jid = nil) # @private
|
156
|
+
@stream = stream
|
157
|
+
@jid = JID.new(jid) if jid
|
158
|
+
self.jid.node ? client_post_init : ready!
|
159
|
+
end
|
160
|
+
|
161
|
+
def unbind # @private
|
162
|
+
call_handler_for(:disconnected, nil) || (EM.reactor_running? && EM.stop)
|
163
|
+
end
|
164
|
+
|
165
|
+
def receive_data(stanza) # @private
|
166
|
+
catch(:halt) do
|
167
|
+
run_filters :before, stanza
|
168
|
+
handle_stanza stanza
|
169
|
+
run_filters :after, stanza
|
170
|
+
end
|
171
|
+
end
|
172
|
+
|
173
|
+
def setup? # @private
|
174
|
+
@setup.is_a? Array
|
175
|
+
end
|
176
|
+
|
177
|
+
def setup(jid, password, host = nil, port = nil) # @private
|
178
|
+
@jid = JID.new(jid)
|
179
|
+
@setup = [@jid, password]
|
180
|
+
@setup << host if host
|
181
|
+
@setup << port if port
|
182
|
+
self
|
183
|
+
end
|
184
|
+
|
185
|
+
protected
|
186
|
+
def stream # @private
|
187
|
+
@stream || raise('Stream not ready!')
|
188
|
+
end
|
189
|
+
|
190
|
+
def check_handler(type, guards) # @private
|
191
|
+
Blather.logger.warn "Handler for type \"#{type}\" will never be called as it's not a registered type" unless current_handlers.include?(type)
|
192
|
+
check_guards guards
|
193
|
+
end
|
194
|
+
|
195
|
+
def current_handlers # @private
|
196
|
+
[:ready, :disconnected] + Stanza.handler_list + BlatherError.handler_list
|
197
|
+
end
|
198
|
+
|
199
|
+
def setup_initial_handlers # @private
|
200
|
+
register_handler :error do |err|
|
201
|
+
raise err
|
202
|
+
end
|
203
|
+
|
204
|
+
# register_handler :iq, :type => [:get, :set] do |iq|
|
205
|
+
# write StanzaError.new(iq, 'service-unavailable', :cancel).to_node
|
206
|
+
# end
|
207
|
+
|
208
|
+
register_handler :status do |status|
|
209
|
+
roster[status.from].status = status if roster[status.from]
|
210
|
+
nil
|
211
|
+
end
|
212
|
+
|
213
|
+
register_handler :roster do |node|
|
214
|
+
roster.process node
|
215
|
+
end
|
216
|
+
end
|
217
|
+
|
218
|
+
def ready! # @private
|
219
|
+
@state = :ready
|
220
|
+
call_handler_for :ready, nil
|
221
|
+
end
|
222
|
+
|
223
|
+
def client_post_init # @private
|
224
|
+
write_with_handler Stanza::Iq::Roster.new do |node|
|
225
|
+
roster.process node
|
226
|
+
write @status
|
227
|
+
ready!
|
228
|
+
end
|
229
|
+
end
|
230
|
+
|
231
|
+
def run_filters(type, stanza) # @private
|
232
|
+
@filters[type].each do |guards, handler, filter|
|
233
|
+
next if handler && !stanza.handler_hierarchy.include?(handler)
|
234
|
+
catch(:pass) { call_handler filter, guards, stanza }
|
235
|
+
end
|
236
|
+
end
|
237
|
+
|
238
|
+
def handle_stanza(stanza) # @private
|
239
|
+
if handler = @tmp_handlers.delete(stanza.id)
|
240
|
+
handler.call stanza
|
241
|
+
else
|
242
|
+
stanza.handler_hierarchy.each do |type|
|
243
|
+
break if call_handler_for(type, stanza)
|
244
|
+
end
|
245
|
+
end
|
246
|
+
end
|
247
|
+
|
248
|
+
def call_handler_for(type, stanza) # @private
|
249
|
+
return unless handler = @handlers[type]
|
250
|
+
handler.find do |guards, handler|
|
251
|
+
catch(:pass) { call_handler handler, guards, stanza }
|
252
|
+
end
|
253
|
+
end
|
254
|
+
|
255
|
+
def call_handler(handler, guards, stanza) # @private
|
256
|
+
if guards.first.respond_to?(:to_str)
|
257
|
+
result = stanza.find(*guards)
|
258
|
+
handler.call(stanza, result) unless result.empty?
|
259
|
+
else
|
260
|
+
handler.call(stanza) unless guarded?(guards, stanza)
|
261
|
+
end
|
262
|
+
end
|
263
|
+
|
264
|
+
# If any of the guards returns FALSE this returns true
|
265
|
+
# the logic is reversed to allow short circuiting
|
266
|
+
# (why would anyone want to loop over more values than necessary?)
|
267
|
+
#
|
268
|
+
# @private
|
269
|
+
def guarded?(guards, stanza)
|
270
|
+
guards.find do |guard|
|
271
|
+
case guard
|
272
|
+
when Symbol
|
273
|
+
!stanza.__send__(guard)
|
274
|
+
when Array
|
275
|
+
# return FALSE if any item is TRUE
|
276
|
+
!guard.detect { |condition| !guarded?([condition], stanza) }
|
277
|
+
when Hash
|
278
|
+
# return FALSE unless any inequality is found
|
279
|
+
guard.find do |method, test|
|
280
|
+
value = stanza.__send__(method)
|
281
|
+
# last_match is the only method found unique to Regexp classes
|
282
|
+
if test.class.respond_to?(:last_match)
|
283
|
+
!(test =~ value.to_s)
|
284
|
+
elsif test.is_a?(Array)
|
285
|
+
!test.include? value
|
286
|
+
else
|
287
|
+
test != value
|
288
|
+
end
|
289
|
+
end
|
290
|
+
when Proc
|
291
|
+
!guard.call(stanza)
|
292
|
+
end
|
293
|
+
end
|
294
|
+
end
|
295
|
+
|
296
|
+
def check_guards(guards) # @private
|
297
|
+
guards.each do |guard|
|
298
|
+
case guard
|
299
|
+
when Array
|
300
|
+
guard.each { |g| check_guards([g]) }
|
301
|
+
when Symbol, Proc, Hash, String
|
302
|
+
nil
|
303
|
+
else
|
304
|
+
raise "Bad guard: #{guard.inspect}"
|
305
|
+
end
|
306
|
+
end
|
307
|
+
end
|
308
|
+
end # Client
|
309
|
+
|
310
|
+
end # Blather
|
@@ -0,0 +1,170 @@
|
|
1
|
+
module Blather
|
2
|
+
module DSL
|
3
|
+
|
4
|
+
class PubSub
|
5
|
+
attr_accessor :host
|
6
|
+
|
7
|
+
# Create a new pubsub DSL
|
8
|
+
#
|
9
|
+
# @param [Blather::Client] client the client who's connection will be used
|
10
|
+
# @param [#to_s] host the PubSub host
|
11
|
+
def initialize(client, host)
|
12
|
+
@client = client
|
13
|
+
@host = host
|
14
|
+
end
|
15
|
+
|
16
|
+
# Retrieve Affiliations
|
17
|
+
#
|
18
|
+
# @param [#to_s] host the PubSub host (defaults to the initialized host)
|
19
|
+
# @yield [Hash] affiliations See {Blather::Stanza::PubSub::Affiliations#list}
|
20
|
+
def affiliations(host = nil, &callback)
|
21
|
+
request Stanza::PubSub::Affiliations.new(:get, send_to(host)), :list, callback
|
22
|
+
end
|
23
|
+
|
24
|
+
# Retrieve Subscriptions
|
25
|
+
#
|
26
|
+
# @param [#to_s] host the PubSub host (defaults to the initialized host)
|
27
|
+
# @yield [Hash] affiliations See {Blather::Stanza::PubSub::Subscriptions#list}
|
28
|
+
def subscriptions(host = nil, &callback)
|
29
|
+
request Stanza::PubSub::Subscriptions.new(:get, send_to(host)), :list, callback
|
30
|
+
end
|
31
|
+
|
32
|
+
# Discover Nodes
|
33
|
+
#
|
34
|
+
# @param [#to_s] path the node path
|
35
|
+
# @param [#to_s] host the PubSub host (defaults to the initialized host)
|
36
|
+
# @yield [Array<Blather::Stanza::DiscoItems::Item>] items
|
37
|
+
def nodes(path = nil, host = nil, &callback)
|
38
|
+
path ||= '/'
|
39
|
+
stanza = Stanza::DiscoItems.new(:get, path)
|
40
|
+
stanza.to = send_to(host)
|
41
|
+
request stanza, :items, callback
|
42
|
+
end
|
43
|
+
|
44
|
+
# Discover node information
|
45
|
+
#
|
46
|
+
# @param [#to_s] path the node path
|
47
|
+
# @param [#to_s] host the PubSub host (defaults to the initialized host)
|
48
|
+
# @yield [Blather::Stanza::DiscoInfo>] info
|
49
|
+
def node(path, host = nil, &callback)
|
50
|
+
stanza = Stanza::DiscoInfo.new(:get, path)
|
51
|
+
stanza.to = send_to(host)
|
52
|
+
request stanza, nil, callback
|
53
|
+
end
|
54
|
+
|
55
|
+
# Retrieve items for a node
|
56
|
+
#
|
57
|
+
# @param [#to_s] path the node path
|
58
|
+
# @param [Array<#to_s>] list a list of IDs to retrieve
|
59
|
+
# @param [Fixnum, #to_s] max the maximum number of items to return
|
60
|
+
# @param [#to_s] host the PubSub host (defaults to the initialized host)
|
61
|
+
# @yield [Array<Blather::Stanza::PubSub::PubSubItem>] items see {Blather::Stanza::PubSub::Items#items}
|
62
|
+
def items(path, list = [], max = nil, host = nil, &callback)
|
63
|
+
request(
|
64
|
+
Stanza::PubSub::Items.request(send_to(host), path, list, max),
|
65
|
+
:items,
|
66
|
+
callback
|
67
|
+
)
|
68
|
+
end
|
69
|
+
|
70
|
+
# Subscribe to a node
|
71
|
+
#
|
72
|
+
# @param [#to_s] node the node to subscribe to
|
73
|
+
# @param [Blather::JID, #to_s] jid is the jid that should be used.
|
74
|
+
# Defaults to the stripped current JID
|
75
|
+
# @param [#to_s] host the PubSub host (defaults to the initialized host)
|
76
|
+
# @yield [Blather::Stanza] stanza the reply stanza
|
77
|
+
def subscribe(node, jid = nil, host = nil)
|
78
|
+
jid ||= client.jid.stripped
|
79
|
+
stanza = Stanza::PubSub::Subscribe.new(:set, send_to(host), node, jid)
|
80
|
+
request(stanza) { |n| yield n if block_given? }
|
81
|
+
end
|
82
|
+
|
83
|
+
# Unsubscribe from a node
|
84
|
+
#
|
85
|
+
# @param [#to_s] node the node to unsubscribe from
|
86
|
+
# @param [Blather::JID, #to_s] jid is the jid that should be used.
|
87
|
+
# Defaults to the stripped current JID
|
88
|
+
# @param [#to_s] host the PubSub host (defaults to the initialized host)
|
89
|
+
# @yield [Blather::Stanza] stanza the reply stanza
|
90
|
+
def unsubscribe(node, jid = nil, host = nil)
|
91
|
+
jid ||= client.jid.stripped
|
92
|
+
stanza = Stanza::PubSub::Unsubscribe.new(:set, send_to(host), node, jid)
|
93
|
+
request(stanza) { |n| yield n if block_given? }
|
94
|
+
end
|
95
|
+
|
96
|
+
# Publish an item to a node
|
97
|
+
#
|
98
|
+
# @param [#to_s] node the node to publish to
|
99
|
+
# @param [#to_s] payload the payload to send see {Blather::Stanza::PubSub::Publish}
|
100
|
+
# @param [#to_s] host the PubSub host (defaults to the initialized host)
|
101
|
+
# @yield [Blather::Stanza] stanza the reply stanza
|
102
|
+
def publish(node, payload, host = nil)
|
103
|
+
stanza = Stanza::PubSub::Publish.new(send_to(host), node, :set, payload)
|
104
|
+
request(stanza) { |n| yield n if block_given? }
|
105
|
+
end
|
106
|
+
|
107
|
+
# Delete items from a node
|
108
|
+
#
|
109
|
+
# @param [#to_s] node the node to delete from
|
110
|
+
# @param [Array<#to_s>] ids a list of ids to delete
|
111
|
+
# @param [#to_s] host the PubSub host (defaults to the initialized host)
|
112
|
+
# @yield [Blather::Stanza] stanza the reply stanza
|
113
|
+
def retract(node, ids = [], host = nil)
|
114
|
+
stanza = Stanza::PubSub::Retract.new(send_to(host), node, :set, ids)
|
115
|
+
request(stanza) { |n| yield n if block_given? }
|
116
|
+
end
|
117
|
+
|
118
|
+
# Create a node
|
119
|
+
#
|
120
|
+
# @param [#to_s] node the node to create
|
121
|
+
# @param [#to_s] host the PubSub host (defaults to the initialized host)
|
122
|
+
# @yield [Blather::Stanza] stanza the reply stanza
|
123
|
+
def create(node, host = nil)
|
124
|
+
stanza = Stanza::PubSub::Create.new(:set, send_to(host), node)
|
125
|
+
request(stanza) { |n| yield n if block_given? }
|
126
|
+
end
|
127
|
+
|
128
|
+
# Purge all node items
|
129
|
+
#
|
130
|
+
# @param [#to_s] node the node to purge
|
131
|
+
# @param [#to_s] host the PubSub host (defaults to the initialized host)
|
132
|
+
# @yield [Blather::Stanza] stanza the reply stanza
|
133
|
+
def purge(node, host = nil)
|
134
|
+
stanza = Stanza::PubSubOwner::Purge.new(:set, send_to(host), node)
|
135
|
+
request(stanza) { |n| yield n if block_given? }
|
136
|
+
end
|
137
|
+
|
138
|
+
# Delete a node
|
139
|
+
#
|
140
|
+
# @param [#to_s] node the node to delete
|
141
|
+
# @param [#to_s] host the PubSub host (defaults to the initialized host)
|
142
|
+
# @yield [Blather::Stanza] stanza the reply stanza
|
143
|
+
def delete(node, host = nil)
|
144
|
+
stanza = Stanza::PubSubOwner::Delete.new(:set, send_to(host), node)
|
145
|
+
request(stanza) { |n| yield n if block_given? }
|
146
|
+
end
|
147
|
+
|
148
|
+
private
|
149
|
+
def request(node, method = nil, callback = nil, &block)
|
150
|
+
unless block_given?
|
151
|
+
block = lambda do |node|
|
152
|
+
callback.call(method ? node.__send__(method) : node)
|
153
|
+
end
|
154
|
+
end
|
155
|
+
|
156
|
+
client.write_with_handler(node, &block)
|
157
|
+
end
|
158
|
+
|
159
|
+
def send_to(host = nil)
|
160
|
+
raise 'You must provide a host' unless (host ||= @host)
|
161
|
+
host
|
162
|
+
end
|
163
|
+
|
164
|
+
def client
|
165
|
+
@client
|
166
|
+
end
|
167
|
+
end # PubSub
|
168
|
+
|
169
|
+
end # DSL
|
170
|
+
end # Blather
|