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=, #iname, #iname=, #jid, #jid=, #subscription, #subscription=

Methods inherited from XMPPElement

class_for_name_xmlns, #clone, force_xmlns, force_xmlns?, import, name_xmlns, name_xmlns_for_class, #parent=, #set_xml_lang, #typed_add, #xml_lang, #xml_lang=

Methods inherited from REXML::Element

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

Constructor Details

#initialize(stream) ⇒ RosterItem

Initialize an empty RosterItem

[View source]

376
377
378
379
380
381
# File 'lib/xmpp4r/roster/helper/roster.rb', line 376

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

Instance Attribute Details

#presencesObject (readonly)

Tracked (online) presences of this RosterItem


372
373
374
# File 'lib/xmpp4r/roster/helper/roster.rb', line 372

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.

[View source]

453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
# File 'lib/xmpp4r/roster/helper/roster.rb', line 453

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’.

[View source]

512
513
514
515
# File 'lib/xmpp4r/roster/helper/roster.rb', line 512

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

[View source]

422
423
424
425
426
427
# File 'lib/xmpp4r/roster/helper/roster.rb', line 422

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

#online?Boolean

Is any presence of this person on-line?

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

Returns:

  • (Boolean)
[View source]

412
413
414
415
416
417
418
# File 'lib/xmpp4r/roster/helper/roster.rb', line 412

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

#presence(jid) ⇒ Object

Get specific presence

jid
JID

Full JID

[View source]

432
433
434
435
436
437
438
439
# File 'lib/xmpp4r/roster/helper/roster.rb', line 432

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 ServerError upon failure.

[View source]

400
401
402
403
404
405
# File 'lib/xmpp4r/roster/helper/roster.rb', line 400

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

#sendObject

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

[View source]

386
387
388
389
390
# File 'lib/xmpp4r/roster/helper/roster.rb', line 386

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. ;-)

[View source]

481
482
483
484
# File 'lib/xmpp4r/roster/helper/roster.rb', line 481

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 ServerError 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.

[View source]

496
497
498
499
500
501
502
# File 'lib/xmpp4r/roster/helper/roster.rb', line 496

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