Class: Jabber::Roster::Helper
- Inherits:
-
Object
- Object
- Jabber::Roster::Helper
- Defined in:
- lib/vendor/xmpp4r/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.
-
#wait_for_roster ⇒ Object
Wait for first roster query result to arrive.
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 wait_for_roster.
Attention: If you send presence and receive presences before the roster has arrived, the Roster helper will let them pass through and does not keep them!
39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 |
# File 'lib/vendor/xmpp4r/lib/xmpp4r/roster/helper/roster.rb', line 39 def initialize(stream) @stream = stream @items = {} @items_lock = Mutex.new @roster_wait = Semaphore.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| if iq.query.kind_of?(IqQueryRoster) Thread.new do Thread.current.abort_on_exception = true handle_iq_query_roster(iq) end true else false end } stream.add_presence_callback(120, self) { |pres| Thread.new do Thread.current.abort_on_exception = true 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/vendor/xmpp4r/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
244 245 246 247 248 249 250 251 252 253 254 255 256 |
# File 'lib/vendor/xmpp4r/lib/xmpp4r/roster/helper/roster.rb', line 244 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
347 348 349 350 351 352 353 354 355 356 |
# File 'lib/vendor/xmpp4r/lib/xmpp4r/roster/helper/roster.rb', line 347 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) 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. ServerError 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
323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 |
# File 'lib/vendor/xmpp4r/lib/xmpp4r/roster/helper/roster.rb', line 323 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) # Adding to list is handled by handle_iq_query_roster 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)
116 117 118 |
# File 'lib/vendor/xmpp4r/lib/xmpp4r/roster/helper/roster.rb', line 116 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
89 90 91 |
# File 'lib/vendor/xmpp4r/lib/xmpp4r/roster/helper/roster.rb', line 89 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
131 132 133 |
# File 'lib/vendor/xmpp4r/lib/xmpp4r/roster/helper/roster.rb', line 131 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
154 155 156 |
# File 'lib/vendor/xmpp4r/lib/xmpp4r/roster/helper/roster.rb', line 154 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
102 103 104 |
# File 'lib/vendor/xmpp4r/lib/xmpp4r/roster/helper/roster.rb', line 102 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
361 362 363 364 |
# File 'lib/vendor/xmpp4r/lib/xmpp4r/roster/helper/roster.rb', line 361 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.
261 262 263 264 265 266 267 268 269 270 271 272 |
# File 'lib/vendor/xmpp4r/lib/xmpp4r/roster/helper/roster.rb', line 261 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]
297 298 299 300 301 302 303 304 305 306 |
# File 'lib/vendor/xmpp4r/lib/xmpp4r/roster/helper/roster.rb', line 297 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)
280 281 282 283 284 285 286 287 288 289 |
# File 'lib/vendor/xmpp4r/lib/xmpp4r/roster/helper/roster.rb', line 280 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 |
#wait_for_roster ⇒ Object
Wait for first roster query result to arrive
77 78 79 80 |
# File 'lib/vendor/xmpp4r/lib/xmpp4r/roster/helper/roster.rb', line 77 def wait_for_roster @roster_wait.wait @roster_wait.run end |