shingara-blather 0.4.8
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.
- 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
|