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