Class: Jabber::Observable::PubSub

Inherits:
Object
  • Object
show all
Defined in:
lib/xmpp4r-observable.rb

Overview

Jabber::Observable::PubSub - Convenience subclass to deal with PubSub

Defined Under Namespace

Classes: AlreadySet, NoService

Instance Method Summary collapse

Constructor Details

#initialize(observable) ⇒ PubSub

Creates a new PubSub object

observable

points a Jabber::Observable object



100
101
102
103
104
105
106
107
108
109
110
111
# File 'lib/xmpp4r-observable.rb', line 100

def initialize(observable)
	@observable = observable

	@helper = @service_jid = nil
	begin
		domain = Jabber::JID.new(@observable.jid).domain
		@service_jid = "pubsub." + domain
		set_service(@service_jid)
	rescue
		@helper = @service_jid = nil
	end
end

Instance Method Details

#create_node(node) ⇒ Object

Create a PubSub node (Lots of options still have to be encoded!)



181
182
183
184
185
186
187
188
189
190
191
# File 'lib/xmpp4r-observable.rb', line 181

def create_node(node)
	raise_noservice if ! has_service?
	begin
		@helper.create_node(node)
	rescue => e
		raise e
		return nil
	end
	@my_nodes << node if defined? @my_nodes
	node
end

#delete_node(node) ⇒ Object

Delete a PubSub node (Lots of options still have to be encoded!)



215
216
217
218
219
220
221
222
223
224
225
# File 'lib/xmpp4r-observable.rb', line 215

def delete_node(node)
	raise_noservice if ! has_service?
	begin
		@helper.delete_node(node)
	rescue => e
		raise e
		return nil
	end
	@my_nodes.delete(node) if defined? @my_nodes
	node
end

#get_items_from(node, count = nil) ⇒ Object

Get items from a node



265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
# File 'lib/xmpp4r-observable.rb', line 265

def get_items_from(node, count = nil)
	raise_noservice if ! has_service?

	if is_subscribed_to?(node)
		# FIXME
		# @helper.get_items_from(node, count)
		# ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
		# The above should just work, but I had to reimplement it since OpenFire (the Jabber Server
		# I am testing against) seems to require subids for nodes we're subscribed to.
		subids = find_subids_for(node)
		iq = Jabber::Iq.new(:get, @service_jid)
		iq.add(Jabber::PubSub::IqPubSub.new)
		iq.from = @observable.jid
		items = Jabber::PubSub::Items.new
		items.node = node
		items.max_items = count
		items.subid = subids[0]
		iq.pubsub.add(items)
		res = nil
		@observable.client.send_with_id(iq) { |reply|
			if reply.kind_of?(Jabber::Iq) and reply.pubsub and reply.pubsub.first_element('items')
				res = {}
				reply.pubsub.first_element('items').each_element('item') do |item|
					res[item.attributes['id']] = item.children.first if item.children.first
				end
			end
			true
		}
		res
	else
		@helper.get_items_from(node, count)
	end
end

#has_service?Boolean

Checks if the PubSub service is set

Returns:

  • (Boolean)


122
123
124
# File 'lib/xmpp4r-observable.rb', line 122

def has_service?
	! @helper.nil?
end

#inspectObject

:nodoc:



113
114
115
116
117
118
119
# File 'lib/xmpp4r-observable.rb', line 113

def inspect	#:nodoc:
	if has_service?
		sprintf("#<%s:0x%x @service_jid=%s>", self.class.name, __id__, @service_jid)
	else
		sprintf("#<%s:0x%x @has_service?=false>", self.class.name, __id__)
	end
end

#is_subscribed_to?(node) ⇒ Boolean

Return true if we’re subscribed to that node

Returns:

  • (Boolean)


206
207
208
209
210
211
212
# File 'lib/xmpp4r-observable.rb', line 206

def is_subscribed_to?(node)
	ret = false
	subscriptions.each do |sub|
		ret = true if sub.node == node and sub.attributes['subscription'] == 'subscribed'
	end
	return ret
end

#my_nodesObject

Return an array of noes I own



194
195
196
197
198
199
200
201
202
203
# File 'lib/xmpp4r-observable.rb', line 194

def my_nodes
	if ! defined? @my_nodes
		ret = []
		subscriptions.each do |sub|
			 ret << sub.node if sub.attributes['affiliation'] == 'owner'
		end
		@my_nodes = ret
	end
	return @my_nodes
end

#publish_atom_item(node, title, body, time = Time.now) ⇒ Object

Publish atom Item. This is an item with one atom entry with title, body and time.



245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
# File 'lib/xmpp4r-observable.rb', line 245

def publish_atom_item(node, title, body, time = Time.now)
	raise_noservice if ! has_service?
	
	item = Jabber::PubSub::Item.new
	entry = REXML::Element.new('entry')
	entry.add_namespace("http://www.w3.org/2005/Atom")
	mytitle = REXML::Element.new('title')
	mytitle.text = title
	entry.add(mytitle)
	mybody = REXML::Element.new('body')
	mybody.text = body
	entry.add(mybody)
	published = REXML::Element.new("published")
	published.text = time.utc.iso8601
	entry.add(published)
	item.add(entry)
	publish_item(node, item)
end

#publish_item(node, item) ⇒ Object

Publish an Item. This infers an item of Jabber::PubSub::Item kind is passed



228
229
230
231
# File 'lib/xmpp4r-observable.rb', line 228

def publish_item(node, item)
	raise_noservice if ! has_service?
	@helper.publish_item_to(node, item)
end

#publish_simple_item(node, text) ⇒ Object

Publish Simple Item. This is an item with one element and some text to it.



234
235
236
237
238
239
240
241
242
# File 'lib/xmpp4r-observable.rb', line 234

def publish_simple_item(node, text)
	raise_noservice if ! has_service?
	
	item = Jabber::PubSub::Item.new
	xml = REXML::Element.new('value')
	xml.text = text
	item.add(xml)
	publish_item(node, item)
end

#set_service(service) ⇒ Object

Sets the PubSub service. Just one service is allowed.

Raises:



127
128
129
130
131
132
133
134
135
136
137
# File 'lib/xmpp4r-observable.rb', line 127

def set_service(service)
	raise NotConnected, "You are not connected" if ! @observable.connected?
	raise AlreadySet, "You already have a PubSub service (#{@service_jid})." if has_service?
	@helper = Jabber::PubSub::ServiceHelper.new(@observable.client, service)
	@service_jid = service
	
	@helper.add_event_callback do |event|
		@observable.changed(:event)
		@observable.notify_observers(:event, event)
	end
end

#subscribe_to(node) ⇒ Object

Subscribe to a node.



140
141
142
143
# File 'lib/xmpp4r-observable.rb', line 140

def subscribe_to(node)
	raise_noservice if ! has_service?
	@helper.subscribe_to(node)
end

#subscriptionsObject

Return the subscriptions we have in the configured PubSub service.



175
176
177
178
# File 'lib/xmpp4r-observable.rb', line 175

def subscriptions
	raise_noservice if ! has_service?
	@helper.get_subscriptions_from_all_nodes()
end

#unsubscribe_from(node) ⇒ Object

Unsubscribe from a node.



146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
# File 'lib/xmpp4r-observable.rb', line 146

def unsubscribe_from(node)
	raise_noservice if ! has_service?
	
	# FIXME
	# @helper.unsubscribe_from(node)
	# ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
	# The above should just work, but I had to reimplement it since XMPP4R doesn't support subids
	# and OpenFire (the Jabber Server I am testing against) seems to require it.
	
	subids = find_subids_for(node)
	return if subids.empty?
	
	subids.each do |subid|
		iq = Jabber::Iq.new(:set, @service_jid)
		iq.add(Jabber::PubSub::IqPubSub.new)
		iq.from = @jid
		unsub = REXML::Element.new('unsubscribe')
		unsub.attributes['node'] = node
		unsub.attributes['jid'] = @jid
		unsub.attributes['subid'] = subid
		iq.pubsub.add(unsub)
		res = nil
		@observable.client.send_with_id(iq) do |reply|
			res = reply.kind_of?(Jabber::Iq) and reply.type == :result
		end # @stream.send_with_id(iq)
	end
end