Class Jabber::Helpers::Roster
In: lib/xmpp4r/helpers/roster.rb
Parent: Object
X XDelay XMuc XRoster XMucUser REXML::Element XRosterItem IqQuery XMLStanza IqVcard DiscoIdentity XMucUserItem DiscoItem Error RosterItem DiscoFeature IqQueryRoster IqQueryVersion IqQueryDiscoItems IqQueryDiscoInfo Message Presence Iq Singleton IdGenerator Connection Client Component Comparable JID RuntimeError ErrorException AuthenticationFailure RosterItem Stream StreamParser Roster Vcard Version lib/xmpp4r/authenticationfailure.rb lib/xmpp4r/iq/query/roster.rb lib/xmpp4r/idgenerator.rb lib/xmpp4r/iq/query/version.rb lib/xmpp4r/connection.rb lib/xmpp4r/x/mucuseritem.rb lib/xmpp4r/x/roster.rb lib/xmpp4r/iq.rb lib/xmpp4r/jid.rb lib/xmpp4r/iq/query.rb lib/xmpp4r/xmlstanza.rb lib/xmpp4r/x/delay.rb lib/xmpp4r/errorexception.rb lib/xmpp4r/client.rb lib/xmpp4r/stream.rb lib/xmpp4r/x/muc.rb lib/xmpp4r/streamparser.rb lib/xmpp4r/x.rb lib/xmpp4r/iq/vcard.rb lib/xmpp4r/iq/query/discoinfo.rb lib/xmpp4r/error.rb lib/xmpp4r/component.rb lib/xmpp4r/message.rb lib/xmpp4r/iq/query/discoitems.rb lib/xmpp4r/presence.rb lib/xmpp4r/helpers/roster.rb lib/xmpp4r/helpers/vcard.rb lib/xmpp4r/helpers/version.rb Helpers Jabber Module: Jabber

The Roster helper intercepts <iq/> stanzas with Jabber::IqQueryRoster and <presence/> stanzas, but provides cbs which allow the programmer to keep track of updates.

Methods

Attributes

items  [R]  All items in your roster
items:[Hash] ([JID] => [Helpers::RosterItem])

Public Class methods

Initialize a new Roster helper

Registers its cbs (prio = 120, ref = "Helpers::Roster")

Request a roster (Remember to send initial presence afterwards!)

[Source]

    # File lib/xmpp4r/helpers/roster.rb, line 28
28:       def initialize(stream)
29:         @stream = stream
30:         @items = {}
31:         @query_cbs = CallbackList.new
32:         @update_cbs = CallbackList.new
33:         @presence_cbs = CallbackList.new
34:         @subscription_cbs = CallbackList.new
35: 
36:         # Register cbs
37:         stream.add_iq_callback(120, "Helpers::Roster") { |iq|
38:           handle_iq(iq)
39:         }
40:         stream.add_presence_callback(120, "Helpers::Roster") { |pres|
41:           handle_presence(pres)
42:         }
43:         
44:         # Request the roster
45:         rosterget = Iq.new_rosterget
46:         stream.send(rosterget)
47:       end

Public Instance methods

Get an item by jid

If not available tries to look for it with the resource stripped

[Source]

     # File lib/xmpp4r/helpers/roster.rb, line 188
188:       def [](jid)
189:         if @items.has_key?(jid)
190:           @items[jid]
191:         elsif @items.has_key?(jid.strip)
192:           @items[jid.strip]
193:         else
194:           nil
195:         end
196:       end

Add a user to your roster

If the item is already in the local roster it will simply send itself

[Source]

     # File lib/xmpp4r/helpers/roster.rb, line 244
244:       def add(jid)
245:         if self[jid]
246:           self[jid].send
247:         else
248:           request = Iq.new_rosterset
249:           request.query.add(Jabber::RosterItem.new(jid))
250:           @stream.send(request)
251:           # Adding to list is handled by handle_iq
252:         end
253:       end

Add a callback for Jabber::Presence updates

This will be called for <presence/> stanzas for known RosterItems. Unknown JIDs may still pass and can be caught via Jabber::Stream#add_presence_callback.

The block receives three objects:

[Source]

    # File lib/xmpp4r/helpers/roster.rb, line 85
85:       def add_presence_callback(prio = 0, ref = nil, proc = nil, &block)
86:         block = proc if proc
87:         @presence_cbs.add(prio, ref, block)
88:       end

Add a callback to be called when a query has been processed

Because update callbacks are called for each roster item, this may be appropriate to notify that anything has updated.

Arguments for callback block: The received <iq/> stanza

[Source]

    # File lib/xmpp4r/helpers/roster.rb, line 56
56:       def add_query_callback(prio = 0, ref = nil, proc = nil, &block)
57:         block = proc if proc
58:         @query_cbs.add(prio, ref, block)
59:       end

Add a callback for subscription updates, which will be called upon receiving a <presence/> stanza with type:

  • :subscribe (you may want to answer with :subscribed or :unsubscribed)
  • :subscribed
  • :unsubscribe
  • :unsubscribed

Warning: if you don’t add a callback here or all callbacks return false subscription requests will be agreed by default in Jabber::Helpers::Roster#handle_presence.

The block receives two objects:

Example usage:

 my_roster.add_subscription_callback do |item,presence|
   if presence.type == :subscribe
     answer = presence.answer(false)
     answer.type = accept_subscription_requests ? :subscribed : :unsubscribed
     client.send(answer)
     true
   else
     false
   end
 end

[Source]

     # File lib/xmpp4r/helpers/roster.rb, line 118
118:       def add_subscription_callback(prio = 0, ref = nil, proc = nil, &block)
119:         block = proc if proc
120:         @subscription_cbs.add(prio, ref, block)
121:       end

Add a callback for Jabber::Helpers::RosterItem updates

Note that this will be called much after initialization for the answer of the initial roster request

The block receives two objects:

[Source]

    # File lib/xmpp4r/helpers/roster.rb, line 70
70:       def add_update_callback(prio = 0, ref = nil, proc = nil, &block)
71:         block = proc if proc
72:         @update_cbs.add(prio, ref, block)
73:       end

Returns the list of RosterItems which, stripped, are equal to the one you are looking for.

[Source]

     # File lib/xmpp4r/helpers/roster.rb, line 201
201:       def find(jid)
202:         j = jid.strip
203:         l = {}
204:         @items.each_pair do |k, v|
205:           l[k] = v if k.strip == j
206:         end
207:         l
208:       end

Get items in a group

When group is nil, return ungrouped items

group:[String] Group name

[Source]

     # File lib/xmpp4r/helpers/roster.rb, line 230
230:       def find_by_group(group)
231:         res = []
232:         @items.each_pair do |jid,item|
233:           res.push(item) if item.groups.include?(group)
234:           res.push(item) if item.groups == [] and group.nil?
235:         end
236:         res
237:       end

Groups in this Roster, sorted by name

Contains nil if there are ungrouped items

result:[Array] containing group names (String)

[Source]

     # File lib/xmpp4r/helpers/roster.rb, line 216
216:       def groups
217:         res = []
218:         @items.each_pair do |jid,item|
219:           res += item.groups
220:           res += [nil] if item.groups == []
221:         end
222:         res.uniq.sort { |a,b| a.to_s <=> b.to_s }
223:       end

Handle received <iq/> stanzas, used internally

[Source]

     # File lib/xmpp4r/helpers/roster.rb, line 126
126:       def handle_iq(iq)
127:         if iq.query.kind_of?(IqQueryRoster)
128:           # If the <iq/> contains <error/> we just ignore that
129:           # and assume an empty roster
130:           iq.query.each_element('item') do |item|
131:             # Handle deletion of item
132:             if item.subscription == :remove
133:               @items.delete(item.jid)
134:               return(true)
135:             end
136:             
137:             olditem = nil
138:             if @items.has_key?(item.jid)
139:               olditem = RosterItem.new(@stream).import(@items[item.jid])
140:               @items[item.jid].import(item)
141:             else
142:               @items[item.jid] = RosterItem.new(@stream).import(item)
143:             end
144:             @update_cbs.process(olditem, @items[item.jid])
145:           end
146: 
147:           @query_cbs.process(iq)
148:         else
149:           false
150:         end
151:       end

Handle received <presence/> stanzas, used internally

[Source]

     # File lib/xmpp4r/helpers/roster.rb, line 156
156:       def handle_presence(pres)
157:         item = self[pres.from]
158:         if [:subscribe, :subscribed, :unsubscribe, :unsubscribed].include?(pres.type)
159:           unless @subscription_cbs.process(item, pres)
160:             @stream.send(Presence.new.set_to(pres.from.strip).set_type(:subscribed))
161:           end
162:           true
163:         else
164:           unless item.nil?
165:             update_presence(item, pres)
166:             true  # Callback consumed stanza
167:           else
168:             false # Callback did not consume stanza
169:           end
170:         end
171:       end

Remove item (also unsubscribes)

jid:[JID]

[Source]

     # File lib/xmpp4r/helpers/roster.rb, line 258
258:       def remove(jid)
259:         request = Iq.new_rosterset
260:         request.query.add(Jabber::RosterItem.new(jid, nil, :remove))
261:         @stream.send(request)
262:         # Removing from list is handled by handle_iq
263:       end

Update the presence of an item, used internally

Callbacks are called here

[Source]

     # File lib/xmpp4r/helpers/roster.rb, line 178
178:       def update_presence(item, pres)
179:         oldpres = item.presence(pres.from).nil? ? nil : Presence.new.import(item.presence(pres.from))
180:         item.add_presence(pres)
181:         @presence_cbs.process(item, oldpres, pres)
182:       end

[Validate]