Class: Jabber::Roster::Helper
- Inherits:
-
Object
- Object
- Jabber::Roster::Helper
- Defined in:
- lib/xmpp4r/roster/helper/roster.rb
Overview
The Roster helper intercepts <iq/>
stanzas with Jabber::IqQueryRoster and <presence/>
stanzas, but provides cbs which allow the programmer to keep track of updates.
A thread for any received stanza is spawned, so the user can invoke accept_subscription et al in the callback blocks, without stopping the current (= parser) thread when waiting for a reply.
Defined Under Namespace
Classes: RosterItem
Instance Attribute Summary collapse
-
#items ⇒ Object
readonly
- All items in your roster items
- Hash
-
([JID] => [Roster::Helper::RosterItem]).
Instance Method Summary collapse
-
#[](jid) ⇒ Object
Get an item by jid.
-
#accept_subscription(jid, iname = nil) ⇒ Object
- Accept a subscription request * Sends a <presence type=‘subscribed’/> stanza * Adds the contact to your roster jid
- JID
- of contact iname
- String
-
Optional roster item name.
-
#add(jid, iname = nil, subscribe = false) ⇒ Object
Add a user to your roster.
-
#add_presence_callback(prio = 0, ref = nil, &block) ⇒ Object
Add a callback for Jabber::Presence updates.
-
#add_query_callback(prio = 0, ref = nil, &block) ⇒ Object
Add a callback to be called when a query has been processed.
-
#add_subscription_callback(prio = 0, ref = nil, &block) ⇒ Object
Add a callback for subscription updates, which will be called upon receiving a
<presence/>
stanza with type: * :subscribed * :unsubscribe * :unsubscribed. -
#add_subscription_request_callback(prio = 0, ref = nil, &block) ⇒ Object
Add a callback for subscription requests, which will be called upon receiving a
<presence type='subscribe'/>
stanza. -
#add_update_callback(prio = 0, ref = nil, &block) ⇒ Object
Add a callback for Jabber::Roster::Helper::RosterItem updates.
-
#decline_subscription(jid) ⇒ Object
Decline a subscription request * Sends a <presence type=‘unsubscribed’/> stanza.
-
#find(jid) ⇒ Object
Returns the list of RosterItems which, stripped, are equal to the one you are looking for.
-
#find_by_group(group) ⇒ Object
Get items in a group.
-
#groups ⇒ Object
Groups in this Roster, sorted by name.
-
#initialize(stream) ⇒ Helper
constructor
Initialize a new Roster helper.
Constructor Details
#initialize(stream) ⇒ Helper
Initialize a new Roster helper
Registers its cbs (prio = 120, ref = self)
Request a roster (Remember to send initial presence afterwards!)
The initialization will not wait for the roster being received, use add_query_callback to get notifyed when Roster::Helper#items has been filled.
36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 |
# File 'lib/xmpp4r/roster/helper/roster.rb', line 36 def initialize(stream) @stream = stream @items = {} @items_lock = Mutex.new @query_cbs = CallbackList.new @update_cbs = CallbackList.new @presence_cbs = CallbackList.new @subscription_cbs = CallbackList.new @subscription_request_cbs = CallbackList.new # Register cbs stream.add_iq_callback(120, self) { |iq| Thread.new do handle_iq(iq) end } stream.add_presence_callback(120, self) { |pres| Thread.new do handle_presence(pres) end } # Request the roster rosterget = Iq.new_rosterget stream.send(rosterget) end |
Instance Attribute Details
#items ⇒ Object (readonly)
All items in your roster
- items
- Hash
-
([JID] => [Roster::Helper::RosterItem])
23 24 25 |
# File 'lib/xmpp4r/roster/helper/roster.rb', line 23 def items @items end |
Instance Method Details
#[](jid) ⇒ Object
Get an item by jid
If not available tries to look for it with the resource stripped
239 240 241 242 243 244 245 246 247 248 249 250 251 |
# File 'lib/xmpp4r/roster/helper/roster.rb', line 239 def [](jid) jid = JID.new(jid) unless jid.kind_of? JID @items_lock.synchronize { if @items.has_key?(jid) @items[jid] elsif @items.has_key?(jid.strip) @items[jid.strip] else nil end } end |
#accept_subscription(jid, iname = nil) ⇒ Object
Accept a subscription request
-
Sends a <presence type=‘subscribed’/> stanza
-
Adds the contact to your roster
- jid
- JID
-
of contact
- iname
- String
-
Optional roster item name
342 343 344 345 346 347 348 349 350 351 |
# File 'lib/xmpp4r/roster/helper/roster.rb', line 342 def accept_subscription(jid, iname=nil) pres = Presence.new.set_type(:subscribed).set_to(jid.strip) @stream.send(pres) unless self[jid.strip] request = Iq.new_rosterset request.query.add(Jabber::Roster::RosterItem.new(jid.strip, iname)) @stream.send_with_id(request) { true } end end |
#add(jid, iname = nil, subscribe = false) ⇒ Object
Add a user to your roster
Threading is encouraged as the function waits for a result. ErrorException is thrown upon error.
See Jabber::Roster::Helper::RosterItem#subscribe for details about subscribing. (This method isn’t used here but the same functionality applies.)
If the item is already in the local roster it will simply send itself
- jid
- JID
-
to add
- iname
- String
-
Optional item name
- subscribe
- Boolean
-
Whether to subscribe to this jid
318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 |
# File 'lib/xmpp4r/roster/helper/roster.rb', line 318 def add(jid, iname=nil, subscribe=false) if self[jid] self[jid].send else request = Iq.new_rosterset request.query.add(Jabber::Roster::RosterItem.new(jid, iname)) @stream.send_with_id(request) { true } # Adding to list is handled by handle_iq end if subscribe # Actually the item *should* already be known now, # but we do it manually to exclude conditions. pres = Presence.new.set_type(:subscribe).set_to(jid.strip) @stream.send(pres) end end |
#add_presence_callback(prio = 0, ref = nil, &block) ⇒ Object
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:
-
the Jabber::Roster::Helper::RosterItem
-
the old Jabber::Presence (or nil)
-
the new Jabber::Presence (or nil)
97 98 99 |
# File 'lib/xmpp4r/roster/helper/roster.rb', line 97 def add_presence_callback(prio = 0, ref = nil, &block) @presence_cbs.add(prio, ref, block) end |
#add_query_callback(prio = 0, ref = nil, &block) ⇒ Object
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
70 71 72 |
# File 'lib/xmpp4r/roster/helper/roster.rb', line 70 def add_query_callback(prio = 0, ref = nil, &block) @query_cbs.add(prio, ref, block) end |
#add_subscription_callback(prio = 0, ref = nil, &block) ⇒ Object
Add a callback for subscription updates, which will be called upon receiving a <presence/>
stanza with type:
-
:subscribed
-
:unsubscribe
-
:unsubscribed
The block receives two objects:
-
the Jabber::Roster::Helper::RosterItem (or nil)
-
the
<presence/>
stanza
112 113 114 |
# File 'lib/xmpp4r/roster/helper/roster.rb', line 112 def add_subscription_callback(prio = 0, ref = nil, &block) @subscription_cbs.add(prio, ref, block) end |
#add_subscription_request_callback(prio = 0, ref = nil, &block) ⇒ Object
Add a callback for subscription requests, which will be called upon receiving a <presence type='subscribe'/>
stanza
The block receives two objects:
-
the Jabber::Roster::Helper::RosterItem (or nil)
-
the
<presence/>
stanza
Response to this event can be taken with accept_subscription and decline_subscription.
Example usage:
my_roster.add_subscription_request_callback do |item,presence|
if accept_subscription_requests
my_roster.accept_subscription(presence.from)
else
my_roster.decline_subscription(presence.from)
end
end
135 136 137 |
# File 'lib/xmpp4r/roster/helper/roster.rb', line 135 def add_subscription_request_callback(prio = 0, ref = nil, &block) @subscription_request_cbs.add(prio, ref, block) end |
#add_update_callback(prio = 0, ref = nil, &block) ⇒ Object
Add a callback for Jabber::Roster::Helper::RosterItem updates
Note that this will be called much after initialization for the answer of the initial roster request
The block receives two objects:
-
the old Jabber::Roster::Helper::RosterItem
-
the new Jabber::Roster::Helper::RosterItem
83 84 85 |
# File 'lib/xmpp4r/roster/helper/roster.rb', line 83 def add_update_callback(prio = 0, ref = nil, &block) @update_cbs.add(prio, ref, block) end |
#decline_subscription(jid) ⇒ Object
Decline a subscription request
-
Sends a <presence type=‘unsubscribed’/> stanza
356 357 358 359 |
# File 'lib/xmpp4r/roster/helper/roster.rb', line 356 def decline_subscription(jid) pres = Presence.new.set_type(:unsubscribed).set_to(jid.strip) @stream.send(pres) end |
#find(jid) ⇒ Object
Returns the list of RosterItems which, stripped, are equal to the one you are looking for.
256 257 258 259 260 261 262 263 264 265 266 267 |
# File 'lib/xmpp4r/roster/helper/roster.rb', line 256 def find(jid) jid = JID.new(jid) unless jid.kind_of? JID j = jid.strip l = {} @items_lock.synchronize { @items.each_pair do |k, v| l[k] = v if k.strip == j end } l end |
#find_by_group(group) ⇒ Object
Get items in a group
When group is nil, return ungrouped items
- group
- String
-
Group name
- result
-
Array of [RosterItem]
292 293 294 295 296 297 298 299 300 301 |
# File 'lib/xmpp4r/roster/helper/roster.rb', line 292 def find_by_group(group) res = [] @items_lock.synchronize { @items.each_pair do |jid,item| res.push(item) if item.groups.include?(group) res.push(item) if item.groups == [] and group.nil? end } res end |
#groups ⇒ Object
Groups in this Roster, sorted by name
Contains nil
if there are ungrouped items
- result
- Array
-
containing group names (String)
275 276 277 278 279 280 281 282 283 284 |
# File 'lib/xmpp4r/roster/helper/roster.rb', line 275 def groups res = [] @items_lock.synchronize { @items.each_pair do |jid,item| res += item.groups res += [nil] if item.groups == [] end } res.uniq.sort { |a,b| a.to_s <=> b.to_s } end |