| Class | Jabber::Helpers::Roster |
| In: |
lib/xmpp4r/helpers/roster.rb
|
| Parent: | Object |
The Roster helper intercepts <iq/> stanzas with Jabber::IqQueryRoster and <presence/> stanzas, but provides cbs which allow the programmer to keep track of updates.
| items | [R] |
All items in your roster
|
Initialize a new Roster helper
Registers its cbs (prio = 120, ref = "Helpers::Roster")
Request a roster (Remember to send initial presence afterwards!)
# 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
Get an item by jid
If not available tries to look for it with the resource stripped
# 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
# 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:
# 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
# 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:
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
# 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:
# 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.
# 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 |
# 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) |
# 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
# 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
# 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] |
# 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
# 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