Class: Jabber::Roster::Helper::RosterItem

Inherits:
RosterItem show all
Defined in:
lib/xmpp4r/roster/helper/roster.rb

Overview

These are extensions to RosterItem to carry presence information. This information is not stored in XML!

Instance Attribute Summary collapse

Instance Method Summary collapse

Methods inherited from RosterItem

#ask, #ask=, #groups, #groups=, import, #iname, #iname=, #jid, #jid=, #subscription, #subscription=

Methods inherited from REXML::Element

#delete_elements, #first_element, #first_element_text, import, #replace_element_text, #typed_add

Constructor Details

#initialize(stream) ⇒ RosterItem

Initialize an empty RosterItem



356
357
358
359
360
361
# File 'lib/xmpp4r/roster/helper/roster.rb', line 356

def initialize(stream)
  super()
  @stream = stream
  @presences = []
  @presences_lock = Mutex.new
end

Instance Attribute Details

#presencesObject (readonly)

Tracked (online) presences of this RosterItem



352
353
354
# File 'lib/xmpp4r/roster/helper/roster.rb', line 352

def presences
  @presences
end

Instance Method Details

#add_presence(newpres) ⇒ Object

Add presence and sort presences (unless type is :unavailable or :error)

This overwrites previous stanzas with the same destination JID to keep track of resources. Presence stanzas with type == :unavailable or type == :error will be deleted as this indicates that this resource has gone offline.

If type == :error and the presence’s origin has no specific resource the contact is treated completely offline.



447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
# File 'lib/xmpp4r/roster/helper/roster.rb', line 447

def add_presence(newpres)
  @presences_lock.synchronize {
    # Delete old presences with the same JID
    @presences.delete_if do |pres|
      pres.from == newpres.from or pres.from.resource.nil?
    end

    if newpres.type == :error and newpres.from.resource.nil?
      # Replace by single error presence
      @presences = [newpres]
    else
      # Add new presence
      @presences.push(newpres)
    end

    @presences.sort!
  }
end

#cancel_subscriptionObject

Deny the contact to see your presence.

This method will not wait and returns immediately as you will need no confirmation for this action.

Though, you will get a roster update for that item, carrying either subscription=‘to’ or ‘none’.



506
507
508
509
# File 'lib/xmpp4r/roster/helper/roster.rb', line 506

def cancel_subscription
  pres = Presence.new.set_type(:unsubscribed).set_to(jid)
  @stream.send(pres)
end

#each_presence(&block) ⇒ Object

Iterate through all received <presence/> stanzas



416
417
418
419
420
421
# File 'lib/xmpp4r/roster/helper/roster.rb', line 416

def each_presence(&block)
  # Don't lock here, we don't know what block does...
  @presences.each { |pres|
    yield(pres)
  }
end

#import(xe) ⇒ Object

Import another element, also import presences if xe is a RosterItem

return
RosterItem

self



367
368
369
370
371
372
373
374
375
# File 'lib/xmpp4r/roster/helper/roster.rb', line 367

def import(xe)
  super
  if xe.kind_of?(RosterItem)
    xe.each_presence { |pres|
      add_presence(Presence.new.import(pres))
    }
  end
  self
end

#online?Boolean

Is any presence of this person on-line?

(Or is there any presence? Unavailable presences are deleted.)

Returns:

  • (Boolean)


406
407
408
409
410
411
412
# File 'lib/xmpp4r/roster/helper/roster.rb', line 406

def online?
  @presences_lock.synchronize {
    @presences.select { |pres|
      pres.type.nil?
    }.size > 0
  }
end

#presence(jid) ⇒ Object

Get specific presence

jid
JID

Full JID



426
427
428
429
430
431
432
433
# File 'lib/xmpp4r/roster/helper/roster.rb', line 426

def presence(jid)
  @presences_lock.synchronize {
    @presences.each { |pres|
      return(pres) if pres.from == jid
    }
  }
  nil
end

#removeObject

Remove item

This cancels both subscription from the contact to you and from you to the contact.

The methods waits for a roster push from the server (success) or throws ErrorException upon failure.



394
395
396
397
398
399
# File 'lib/xmpp4r/roster/helper/roster.rb', line 394

def remove
  request = Iq.new_rosterset
  request.query.add(Jabber::Roster::RosterItem.new(jid, nil, :remove))
  @stream.send_with_id(request) { true }
  # Removing from list is handled by Roster#handle_iq
end

#sendObject

Send the updated RosterItem to the server, i.e. if you modified iname, groups, …



380
381
382
383
384
# File 'lib/xmpp4r/roster/helper/roster.rb', line 380

def send
  request = Iq.new_rosterset
  request.query.add(self)
  @stream.send(request)
end

#subscribeObject

Send subscription request to the user

The block given to Jabber::Roster::Roster#add_update_callback will be called, carrying the RosterItem with ask=“subscribe”

This function returns immediately after sending the subscription request and will not wait of approval or declination as it may take months for the contact to decide. ;-)



475
476
477
478
# File 'lib/xmpp4r/roster/helper/roster.rb', line 475

def subscribe
  pres = Presence.new.set_type(:subscribe).set_to(jid.strip)
  @stream.send(pres)
end

#unsubscribeObject

Unsubscribe from a contact’s presence

This method waits for a presence with type=‘unsubscribed’ from the contact. It may throw ErrorException upon failure.

subscription attribute of the item is from or none afterwards. As long as you don’t remove that item and subscription=‘from’ the contact is subscribed to your presence.



490
491
492
493
494
495
496
# File 'lib/xmpp4r/roster/helper/roster.rb', line 490

def unsubscribe
  pres = Presence.new.set_type(:unsubscribe).set_to(jid.strip)
  @stream.send(pres) { |answer|
    answer.type == :unsubscribed and
    answer.from.strip == pres.to
  }
end