class GxG::Networking::XmppAgent

XMPP Client

Public Class Methods

new(options={}) click to toggle source

Initialization

# File lib/gxg/net_clients.rb, line 3564
def initialize(options={})
  @client = nil
  @pubsub = nil
  @roster = nil
  @browser = nil
  @transfer_manager = nil
  @xfr_callbacks = nil
  @conversations = []
  @conversation_thread_safety = ::Mutex.new
  @invitations = []
  @invitation_thread_safety = ::Mutex.new
  @download_directory = ::File.expand_path(".")
  @file_transfers = []
  @file_transfers_thread_safety = ::Mutex.new
  @notification_object = options[:notify]
  self
end
online_availability_values() click to toggle source
# File lib/gxg/net_clients.rb, line 3146
def self.online_availability_values()
  {:online => :chat, :busy => :dnd, :away => :away, :extended_away => :xa, :offline => :unavailable, :error => :error}
end
register_with_server(the_url=nil, fields={}) click to toggle source
# File lib/gxg/net_clients.rb, line 3233
def self.register_with_server(the_url=nil, fields={})
    # Review : convert this code to Blather compatible
    # Note : see https://www.rubydoc.info/gems/blather/Blather/Stanza/Iq for researching ideas.
    # Note : see https://www.rubydoc.info/gems/xmpp4r/Jabber/Client#register-instance_method for researching ideas.
    result = false
    begin
        if the_url.is_a?(::URI::Generic)
        if the_url.password() == nil
            raise ArgumentError, "You MUST provide a vailid password."
        else
            fields['password'] = the_url.password.to_s
        end
        the_jid = ""
        if the_url.user()
            the_jid << the_url.user.to_s
            fields['username'] = the_url.user.to_s
        else
            raise ArgumentError, "You MUST provide a vailid user name."
        end
        if the_url.hostname()
            the_jid << ("@" + the_url.hostname.to_s)
        else
            raise ArgumentError, "You MUST provide a vailid host or IP Address."
        end
        if the_url.path()
            the_jid << ("/" + File.basename(the_url.path.to_s))
        end
        # xxx
        # client = ::Jabber::Client.new(the_jid)
        # client.connect(the_url.hostname.to_s, (the_url.port || 5222))
        # valid_fields = ::GxG::Networking::XmppClient::registration_fields().keys
        # the_fields = {}
        # fields.each_pair do |key, entry|
        #     if valid_fields.include?(key.to_sym)
        #     the_fields[(key.to_s)] = entry
        #     end
        # end
        # if the_fields.keys.size > 0
        #     client.register(the_url.password.to_s, the_fields)
        # else
        #     client.register(the_url.password.to_s)
        # end
        # if client.status == 2
        #     client.close
        # end
        result = true
        else
        raise ArgumentError, "You MUST provide a vailid URL."
        end
    rescue Exception => the_error
        log_error({:error => the_error, :parameters => {:url => the_url, :fields => fields}})
    end
    result
end
registration_fields() click to toggle source
# File lib/gxg/net_clients.rb, line 3150
def self.registration_fields()
  # XEP-0077 Support
  {:username => 'Account name associated with the user', :nick => 'Familiar name of the user', :password => 'Password or secret for the user', :name => 'Full name of the user', :first => 'First name or given name of the user', :last => 'Last name, surname, or family name of the user', :email => 'Email address of the user', :address => 'Street portion of a physical or mailing address', :city => 'Locality portion of a physical or mailing address', :state => 'Region portion of a physical or mailing address', :zip => 'Postal code portion of a physical or mailing address', :phone => 'Telephone number of the user', :url => 'URL to web page describing the user', :date => 'Some date (e.g., birth date, hire date, sign-up date)'}.clone
end
registration_info(the_url=nil) click to toggle source
# File lib/gxg/net_clients.rb, line 3155
def self.registration_info(the_url=nil)
  result = nil
  begin
    if the_url.is_a?(::URI::Generic)
        the_jid = "anonymous"
        if the_url.hostname()
            the_jid << ("@" + the_url.hostname.to_s)
        else
            raise ArgumentError, "You MUST provide a vailid host or IP Address in a valid URI."
        end
        # Review : convert this code to Blather compatible
        # Note : see https://www.rubydoc.info/gems/blather/Blather/Stanza/Iq for researching ideas.
        # Note : see https://www.rubydoc.info/gems/xmpp4r/Jabber/Client#register-instance_method for researching ideas.
        result = []
        #   client = ::Jabber::Client.new(the_jid)
        #   client.connect(the_url.hostname.to_s, (the_url.port || 5222))
        #   info = client.register_info()
        #   if client.status == 2
        #     client.close
        #   end
        #   if info.is_a?(::Array)
        #     fields = ::GxG::Networking::XmppClient::registration_fields()
        #     result = {:instructions => info[0], :registration_fields => {}}
        #     info[1].each do |the_raw_key|
        #       result[:registration_fields][(the_raw_key.to_sym)] = fields[(the_raw_key.to_sym)]
        #     end
        #   end
    else
      raise ArgumentError, "You MUST provide a vailid URL."
    end
  rescue Exception => the_error
    log_error({:error => the_error, :parameters => {:url => the_url}})
  end
  result
end
remove_registration(the_url=nil) click to toggle source
# File lib/gxg/net_clients.rb, line 3191
def self.remove_registration(the_url=nil)
    # Review : convert this code to Blather compatible
    # Note : see https://www.rubydoc.info/gems/blather/Blather/Stanza/Iq for researching ideas.
    # Note : see https://www.rubydoc.info/gems/xmpp4r/Jabber/Client#register-instance_method for researching ideas.
    result = false
    begin
        if the_url.is_a?(::URI::Generic)
        if the_url.password() == nil
            raise ArgumentError, "You MUST provide a vailid password."
        end
        the_jid = ""
        if the_url.user()
            the_jid << the_url.user.to_s
        else
            raise ArgumentError, "You MUST provide a vailid user name."
        end
        if the_url.hostname()
            the_jid << ("@" + the_url.hostname.to_s)
        else
            raise ArgumentError, "You MUST provide a vailid host or IP Address."
        end
        if the_url.path()
            the_jid << ("/" + File.basename(the_url.path.to_s))
        end
        # Here ???
        # Connect
        client = ::Blather::Client::setup(the_jid, the_url.password.to_s, the_url.hostname.to_s, (the_url.port || 5222))
        client.run
        # xxx
        # client.remove_registration
        # xxx
        client.close
        result = true
        else
        raise ArgumentError, "You MUST provide a vailid URL."
        end
    rescue Exception => the_error
        log_error({:error => the_error, :parameters => {:url => the_url, :fields => fields}})
    end
    result
end

Public Instance Methods

<<(stanza) click to toggle source
# File lib/gxg/net_clients.rb, line 3296
def <<(stanza)
    if @client
        @client.write stanza
    end
    self
end
add_buddy(the_jid=nil) click to toggle source
# File lib/gxg/net_clients.rb, line 3798
def add_buddy(the_jid=nil)
  result = false
  begin
    if @client
      if the_jid.is_a?(::String)
        unless the_jid.valid_jid?
          raise ArgumentError, "You MUST provide a valid JID string."
        end
        @client.write(Blather::Stanza::Presence::Subscription.new(::Blather::JID.new(the_jid), "subscribe"))
        result = true
      end
    end
  rescue Exception => the_error
    log_error({:error => the_error, :parameters => {:the_jid => the_jid}})
  end
  result
end
after(handler = nil, *guards, &block) click to toggle source

### Setup an after filter

@param [Symbol] handler (optional) the stanza handler the filter should run after @param [guards] guards (optional) a set of guards to check the stanza against @yield [Blather::Stanza] stanza

# File lib/gxg/net_clients.rb, line 3325
def after(handler = nil, *guards, &block)
    if @client
        @client.register_filter :after, handler, *guards, &block
    end
end
before(handler = nil, *guards, &block) click to toggle source

### Setup a before filter

@param [Symbol] handler (optional) the stanza handler the filter should run before @param [guards] guards (optional) a set of guards to check the stanza against @yield [Blather::Stanza] stanza

# File lib/gxg/net_clients.rb, line 3313
def before(handler = nil, *guards, &block)
    if @client
        @client.register_filter :before, handler, *guards, &block
    end
end
buddies() click to toggle source
# File lib/gxg/net_clients.rb, line 3777
def buddies()
    result = []
    begin
        if @client
            @client.roster.items.each_pair do |key_object, data|
                new_record = {:jid => "", :title => "Untitled", :groups => [], :status => :offline}
                new_record[:jid] = key_object.to_s
                new_record[:title] = data.name.to_s
                new_record[:groups] = data.groups
                if data.status()
                    new_record[:status] = data.status().state()
                end
                result << new_record
            end
        end
    rescue Exception => the_error
        log_error({:error => the_error, :parameters => {}})
    end
    result
end
client() click to toggle source

Review : debug only method

# File lib/gxg/net_clients.rb, line 3582
def client()
    @client
end
conversations(select_jid=nil) click to toggle source
# File lib/gxg/net_clients.rb, line 3902
def conversations(select_jid=nil)
  result = []
  begin
    if @client
      @conversation_thread_safety.synchronize {
        @conversations.each do |entry|
            if select_jid
                if select_jid.to_s == entry.jid.to_s
                    unless entry.closed?
                        result << entry
                        break
                    end
                end
            else
                unless entry.closed?
                    result << entry
                end
            end
        end
      }
    end
  rescue Exception => the_error
    log_error({:error => the_error, :parameters => {}})
  end
  result
end
create_conversation(the_jid=nil, password=nil, configuration={}) click to toggle source
# File lib/gxg/net_clients.rb, line 3929
def create_conversation(the_jid=nil, password=nil, configuration={})
  result = false
  begin
    if @client
      unless the_jid.is_a?(::String)
        raise ArgumentError, "You MUST provide a valid JID String."
      end
      unless the_jid.valid_jid?()
        raise ArgumentError, "You MUST provide a valid JID String. The one you provided is malformed."
      end
      if (self.buddies.collect {|entry| entry[:jid]}).include?(the_jid)
        # private channel
        the_channel = self.conversations(the_jid)[0]
        unless the_channel
            the_channel = ::GxG::Networking::XmppAgentConversation.new(self, {:sender => the_jid, :type => :chat})
            @conversation_thread_safety.synchronize { @conversations << the_channel }
        end
      else
        # groupchat channel
        the_channel = self.conversations(the_jid)[0]
        unless the_channel
            the_channel = ::GxG::Networking::XmppAgentConversation.new(self, {:sender => the_jid, :type => :groupchat})
            @conversation_thread_safety.synchronize { @conversations << the_channel }
        end
        if the_channel
            the_channel.join(the_jid)
            if configuration.is_any?(::Hash, ::GxG::Database::PersistedHash)
              if configuration.keys.size > 0
                the_channel.change_configuration(configuration)
              end
            end
        end
      end
      result = true
    end
  rescue Exception => the_error
    log_error({:error => the_error, :parameters => {:jid => the_jid}})
  end
  result
end
disconnected(&block) click to toggle source

### Wrapper for “handle :disconnected”

This is run after the connection has been shut down.

@example Reconnect after a disconnection

disconnected { client.run }
# File lib/gxg/net_clients.rb, line 3353
def disconnected(&block)
    self.handle :disconnected, &block
end
discover(what, who, where, &callback) click to toggle source

### Request items or info from an entity

discover (items|info), [jid], [node] do |response|
end
# File lib/gxg/net_clients.rb, line 3479
def discover(what, who, where, &callback)
    if @client
        stanza = Blather::Stanza.class_from_registration(:query, "http://jabber.org/protocol/disco##{what}").new
        stanza.to = who
        stanza.node = where
  
        @client.register_tmp_handler stanza.id, &callback
        @client.write stanza
    end
end
download_directory() click to toggle source
# File lib/gxg/net_clients.rb, line 3994
def download_directory()
  @file_transfers_thread_safety.synchronize { @download_directory }
end
download_directory=(the_path=nil) click to toggle source
# File lib/gxg/net_clients.rb, line 3998
def download_directory=(the_path=nil)
  unless the_path.is_a?(::String)
    raise ArgumentError, "You MUST supply a String as valid file path."
  end
  the_path = ::File.expand_path(the_path)
  unless the_path.valid_path?()
    raise ArgumentError, "You MUST supply a valid file path."
  end
  unless ::File.exist?(the_path)
    raise ArgumentError, "You MUST supply a valid file path - File does not exist."
  end
  @file_transfers_thread_safety.synchronize { @download_directory = the_path }
end
file_transfers() click to toggle source
# File lib/gxg/net_clients.rb, line 4057
def file_transfers()
  result = []
  if @client
    begin
      @file_transfers.each do |entry|
        if (entry.pending? || entry.in_progress? || entry.percent_completed < 100)
          result << entry
        end
      end
    rescue Exception => the_error
      log_error({:error => the_error, :parameters => {}})
    end
  end
  result
end
find_file_transfer(reference=nil, use_session = false) click to toggle source
# File lib/gxg/net_clients.rb, line 4104
def find_file_transfer(reference=nil, use_session = false)
  result = nil
  begin
    if @client
      manifest = []
      @file_transfers_thread_safety.synchronize {
        @file_transfers.each do |entry|
          manifest << entry
        end
      }
      manifest.each do |entry|
        if use_session == true
          if (reference == entry.session_id())
            result = entry
            break
          end
        else
          if (reference == entry.reference())
            result = entry
            break
          end
        end
      end
    end
  rescue Exception => the_error
    log_error({:error => the_error, :parameters => {}})
  end
  result
end
get_status() click to toggle source
# File lib/gxg/net_clients.rb, line 3367
def get_status()
    if @client
        @client.status
    else
        :unavailable
    end
end
gxg_message_to_xmpp(the_message=nil) click to toggle source
# File lib/gxg/net_clients.rb, line 3535
def gxg_message_to_xmpp(the_message=nil)
  # need: :to, :body, :state, :subject, :context, :type
  # ::Celluloid::UUID::random_generate().to_s
  unless the_message.is_a?(::GxG::Events::Message)
    raise ArgumentError, "You MUST provide a valid message object: GxG::Events::Message or new_message Hash."
  end
  xmpp_message = Blather::Stanza::Message.new(the_message[:to], the_message[:body])
  # chat states: active composing gone inactive paused
  # xmpp_message.set_chat_state(the_message[:state].to_s.to_sym)
  xmpp_message.id = (the_message[:id].to_s)
  xmpp_message.from = (the_message[:sender].to_s)
  xmpp_message.to = (the_message[:to].to_s)
  if the_message[:context].to_s.size > 0
    xmpp_message.thread = (the_message[:context].to_s)
  end
  xmpp_message.subject = (the_message[:subject].to_s)
  #
  # The following <type> Symbols are allowed:
  # * :chat
  # * :error
  # * :groupchat
  # * :headline
  # * :normal
  xmpp_message.type = (the_message[:type] || :chat)
  xmpp_message.body = the_message[:body]
  xmpp_message
end
halt() click to toggle source

### Halt the handler chain

Use this to stop the propogation of the stanza though the handler chain.

@example Ignore all IQ stanzas

before(:iq) { halt }
# File lib/gxg/net_clients.rb, line 3456
def halt
    # Review : how to actually use this? I see no way to call 'throw' yet. (research)
    # throw :halt
end
handle(handler, *guards, &block) click to toggle source

### Set handler for a stanza type

@param [Symbol] handler the stanza type it should handle @param [guards] guards (optional) a set of guards to check the stanza against @yield [Blather::Stanza] stanza

# File lib/gxg/net_clients.rb, line 3336
def handle(handler, *guards, &block)
    if @client
        @client.register_handler handler, *guards, &block
    end
end
invitations() click to toggle source
# File lib/gxg/net_clients.rb, line 3834
def invitations()
  result = []
  begin
    if @client
      @invitation_thread_safety.synchronize {
        @invitations.each do |entry|
          if entry.pending?
            result << entry
          end
        end
      }
    end
  rescue Exception => the_error
    log_error({:error => the_error, :parameters => {}})
  end
  result
end
jid() click to toggle source

### The JID according to the server

@return [Blather::JID]

# File lib/gxg/net_clients.rb, line 3417
def jid
    if @client
        @client.jid
    else
        nil
    end
end
jid_domain() click to toggle source
# File lib/gxg/net_clients.rb, line 3433
def jid_domain()
    jid = self.jid
    if jid
        jid.domain()
    else
        nil
    end
end
jid_node() click to toggle source

other supporting JID methods

# File lib/gxg/net_clients.rb, line 3425
def jid_node()
    jid = self.jid
    if jid
        jid.node()
    else
        nil
    end
end
jid_resource() click to toggle source
# File lib/gxg/net_clients.rb, line 3441
def jid_resource()
    jid = self.jid
    if jid
        jid.resource()
    else
        nil
    end
end
join(room, service, nickname = nil) click to toggle source

### Helper method to join a MUC room

@overload join(room_jid, nickname)

 @param [Blather::JID, #to_s] room the JID of the room to join
 @param [#to_s] nickname the nickname to join the room as
@overload join(room_jid, nickname)
 @param [#to_s] room the name of the room to join
 @param [Blather::JID, #to_s] service the service domain the room is hosted at
 @param [#to_s] nickname the nickname to join the room as
# File lib/gxg/net_clients.rb, line 3397
def join(room, service, nickname = nil)
    join = Blather::Stanza::Presence::MUC.new
    if nickname
        join.to = "#{room}@#{service}/#{nickname}"
    else
        join.to = "#{room}/#{service}"
    end
    self.write join
end
join_conversation(the_jid=nil, password=nil, options={}) click to toggle source
# File lib/gxg/net_clients.rb, line 3970
def join_conversation(the_jid=nil, password=nil, options={})
  result = false
  begin
    if @client
      unless the_jid.is_a?(::String)
        raise ArgumentError, "You MUST provide a valid JID String."
      end
      unless the_jid.valid_jid?()
        raise ArgumentError, "You MUST provide a valid JID String. The one you provided is malformed."
      end
      the_channel = self.conversations(the_jid)[0]
      unless the_channel
          the_channel = ::GxG::Networking::XmppAgentConversation.new(self, {:sender => the_jid, :type => :groupchat})
          @conversation_thread_safety.synchronize { @conversations << the_channel }
          the_channel.join(the_jid)
      end
      result = true
    end
  rescue Exception => the_error
    log_error({:error => the_error, :parameters => {:jid => the_jid}})
  end
  result
end
login(the_url=nil, options={}) click to toggle source
# File lib/gxg/net_clients.rb, line 3596
def login(the_url=nil, options={})
    result = false
    begin
        if the_url.is_a?(::URI::Generic)
            if the_url.password() == nil && the_url.user != "anonymous"
            raise ArgumentError, "You MUST provide a vailid password."
            end
            the_jid = ""
            if the_url.user()
            the_jid << the_url.user.to_s
            else
            raise ArgumentError, "You MUST provide a vailid user name."
            end
            if the_url.hostname()
            the_jid << ("@" + the_url.hostname.to_s)
            else
            raise ArgumentError, "You MUST provide a vailid host or IP Address."
            end
            if the_url.path()
            the_jid << ("/" + File.basename(the_url.path.to_s))
            end
            # Connect
            @client = ::Blather::Client::setup(the_jid, the_url.password.to_s, the_url.hostname.to_s, (the_url.port || 5222))
            # @client.run
            # Initialize Supports
            @pubsub = ::Blather::DSL::PubSub.new(@client, self.jid_domain)
            # Auto-reconnect if disconnected
            self.handle :disconnected do
              @client.run
            end
            # ### Setup Message Reception: (skipping compose etc messages for now.)
            # Handlers Map : https://github.com/adhearsion/blather#handlers-hierarchy
            # Private Message (type :normal)
            self.handle :message, :normal?, :body do |message|
              the_message = self.xmpp_message_to_gxg(message)
              the_channel = self.conversations(the_message[:sender].to_s)[0]
              unless the_channel
                  the_channel = ::GxG::Networking::XmppAgentConversation.new(self, {:sender => the_message[:sender], :type => :chat})
                  @conversation_thread_safety.synchronize { @conversations << the_channel }
              end
              the_channel.add_message(the_message)
              self.notify({:event => :new_private_message, :conversation => the_channel.uuid, :message => the_message.id, :sender => the_message[:sender].to_s})
              true
            end
            # Private Message (type :chat)
            self.handle :message, :chat?, :body do |message|
                the_message = self.xmpp_message_to_gxg(message)
                the_channel = self.conversations(the_message[:sender].to_s)[0]
                unless the_channel
                    the_channel = ::GxG::Networking::XmppAgentConversation.new(self, {:sender => the_message[:sender], :type => :chat})
                    @conversation_thread_safety.synchronize { @conversations << the_channel }
                end
                the_channel.add_message(the_message)
                self.notify({:event => :new_private_message, :conversation => the_channel.uuid, :message => the_message.id, :sender => the_message[:sender].to_s})
                true
            end
            # Group Message
            self.handle :message, :groupchat?, :body do |message|
                the_message = self.xmpp_message_to_gxg(message)
                the_channel = self.conversations(the_message[:sender].to_s)[0]
                unless the_channel
                    the_channel = ::GxG::Networking::XmppAgentConversation.new(self, {:sender => the_message[:sender], :type => :groupchat})
                    @conversation_thread_safety.synchronize { @conversations << the_channel }
                end
                the_channel.add_message(the_message)
                self.notify({:event => :new_message, :conversation => the_channel.uuid, :message => the_message.id, :sender => the_message[:sender].to_s})
                true
            end
            # Announcement Message
            self.handle :message, :headline?, :body do |message|
              the_message = self.xmpp_message_to_gxg(message)
              the_channel = self.conversations(the_message[:sender].to_s)[0]
              unless the_channel
                  the_channel = ::GxG::Networking::XmppAgentConversation.new(self, {:sender => the_message[:sender], :type => :chat})
                  @conversation_thread_safety.synchronize { @conversations << the_channel }
              end
              the_channel.add_message(the_message)
              self.notify({:event => :new_announcement, :conversation => the_channel.uuid, :message => the_message.id, :sender => the_message[:sender].to_s})
              true
            end
            # Error Message
            self.handle :message, :error?, :body do |message|
              the_message = self.xmpp_message_to_gxg(message)
              the_channel = self.conversations(the_message[:sender].to_s)[0]
              unless the_channel
                  the_channel = ::GxG::Networking::XmppAgentConversation.new(self, {:sender => the_message[:sender], :type => :chat})
                  @conversation_thread_safety.synchronize { @conversations << the_channel }
              end
              the_channel.add_message(the_message)
              self.notify({:event => :new_error, :conversation => the_channel.uuid, :message => the_message.id, :sender => the_message[:sender].to_s})
              true
            end
            # Presence
            self.handle :iq do |update|
                if update.respond_to?(:type)
                    if update.is_a?(::Blather::Stanza::Iq::Ping)
                        # Auto-reply to Pings:
                        reply = update.reply
                        reply.type = :result
                        # Review : how to add a data payload to the reply?
                        self.write_to_stream(reply)
                    else
                        if update.is_a?(::Blather::Stanza::Iq)
                            # reply = update.reply
                            # reply.type = :result
                            # # Review : how to add a data payload to the reply?
                            # self.write_to_stream(reply)
                            # puts "Got: #{update.class.inspect}\n-----------------------------------------\n#{update.inspect}\n Sent: #{reply.inspect}\n-----------------------------------------\n"
                        end
                    end
                end
                # Note : returning 'false' signals that subsequent process of this stanza is desired.
                false
            end
            # Invitation
            self.handle :subscription do |invitation|
                gxg_invitation = ::GxG::Networking::XmppAgentInvitation.new(self, invitation)
                @invitation_thread_safety.synchronize { @invitations << gxg_invitation }
                self.notify({:event => :new_invitation, :invitation => gxg_invitation.uuid, :sender => gxg_invitation.from.to_s})
                true
            end
            # Presence
            self.handle :presence do |presence_update|
                the_sender = "#{presence_update.from.node.to_s}@#{presence_update.from.domain.to_s}"
                self.my_roster.each do |roster_item|
                    if roster_item.jid.to_s == the_sender
                        roster_item.status = presence_update
                        break
                    end
                end
                false
            end
            # File Transfer
            self.handle :file_transfer do |invitation|
                # gxg_invitation = ::GxG::Networking::XmppAgentInvitation.new(self, invitation)
                # @invitation_thread_safety.synchronize { @invitations << gxg_invitation }
                puts "Got (file transfer) : #{invitation.inspect}"
                false
            end
            # Multi-User Chat (MUC) Invitation
            self.handle :muc_join do |invitation|
                # gxg_invitation = ::GxG::Networking::XmppAgentInvitation.new(self, invitation)
                # @invitation_thread_safety.synchronize { @invitations << gxg_invitation }
                puts "Got (MUC join) : #{invitation.inspect}"
                true
            end
            self.handle :muc_user do |invitation|
                # try also: :muc_user, :invite?
                # gxg_invitation = ::GxG::Networking::XmppAgentInvitation.new(self, invitation)
                # @invitation_thread_safety.synchronize { @invitations << gxg_invitation }
                puts "Got (MUC user) : #{invitation.inspect}"
                true
            end
            # Connect
            @client.run
            result = true
            timeout = Time.now.to_f + 30.0
            until @client.connected? do
                if Time.now.to_f >= timeout
                    result = false
                    break
                end
            end
        end
    rescue Exception => the_error
        puts the_error.to_s
    end
    #
    result
end
logout() click to toggle source
# File lib/gxg/net_clients.rb, line 3767
def logout
    if @client
        @client.clear_handlers :disconnected
        @client.close
        @client = nil
    end
    #
    true
end
my_roster() click to toggle source

### Direct access to the roster

@return [Blather::Roster]

# File lib/gxg/net_clients.rb, line 3377
def my_roster
    if @client
        @client.roster
    end
end
notify(notification_type=nil) click to toggle source
# File lib/gxg/net_clients.rb, line 3586
def notify(notification_type=nil)
  if notification_type
    if @notification_object
      if @notification_object.respond_to?(:notify)
        @notification_object.notify(notification_type)
      end
    end
  end
end
pass() click to toggle source

### Pass responsibility to the next handler

Use this to jump out of the current handler and let the next registered handler take care of the stanza

@example Pass a message to the next handler

This is contrive and should be handled with guards, but pass a message to the next handler based on the content

message { |s| puts "message caught" }
message { |s| pass if s.body =~ /pass along/ }
# File lib/gxg/net_clients.rb, line 3472
def pass
    # Review : how to actually use this? I see no way to call 'throw' yet. (research)
    # throw :pass
end
publish_and_subscribe() click to toggle source
# File lib/gxg/net_clients.rb, line 3303
def publish_and_subscribe
    @pubsub
end
refresh_conversations() click to toggle source
# File lib/gxg/net_clients.rb, line 3877
def refresh_conversations()
  result = false
  begin
    if @client
      deadlist = []
      @conversation_thread_safety.synchronize {
        @conversations.each_index do |index|
          if @conversations[(index)].closed?
            deadlist << index
          end
        end
        if deadlist.size > 0
          deadlist.reverse.each do |the_index|
            @conversations.delete_at(the_index)
          end
        end
        result = true
      }
    end
  rescue Exception => the_error
    log_error({:error => the_error, :parameters => {}})
  end
  result
end
refresh_file_transfers() click to toggle source
# File lib/gxg/net_clients.rb, line 4073
def refresh_file_transfers()
  result = false
  begin
    if @client
      manifest = []
      deadlist = []
      @file_transfers_thread_safety.synchronize {
        @file_transfers.each do |entry|
          manifest << entry
        end
      }
      manifest.each_with_index do |entry, index|
        unless (entry.pending?() || entry.in_progress?())
          deadlist << index
        end
      end
      @file_transfers_thread_safety.synchronize {
        if deadlist.size > 0
          deadlist.reverse.each do |the_index|
            @file_transfers.delete_at(the_index)
          end
        end
      }
      result = true
    end
  rescue Exception => the_error
    log_error({:error => the_error, :parameters => {}})
  end
  result
end
refresh_invitations() click to toggle source
# File lib/gxg/net_clients.rb, line 3852
def refresh_invitations()
  result = false
  begin
    if @client
      deadlist = []
      @invitation_thread_safety.synchronize {
        @invitations.each_index do |index|
          unless @invitations[(index)].pending?
            deadlist << index
          end
        end
        if deadlist.size > 0
          deadlist.reverse.each do |the_index|
            @invitations.delete_at(the_index)
          end
        end
        result = true
      }
    end
  rescue Exception => the_error
    log_error({:error => the_error, :parameters => {}})
  end
  result
end
remove_buddy(the_jid=nil) click to toggle source
# File lib/gxg/net_clients.rb, line 3816
def remove_buddy(the_jid=nil)
  result = false
  begin
    if @client
      if the_jid.is_a?(::String)
        unless the_jid.valid_jid?
          raise ArgumentError, "You MUST provide a valid JID string."
        end
        @client.write(Blather::Stanza::Presence::Subscription.new(::Blather::JID.new(the_jid), "unsubscribe"))
        result = true
      end
    end
  rescue Exception => the_error
    log_error({:error => the_error, :parameters => {:the_jid => the_jid}})
  end
  result
end
say(to, msg, using = :chat) click to toggle source

### Helper method to make sending basic messages easier

@param [Blather::JID, to_s] to the JID of the message recipient @param [#to_s] msg the message to send @param [#to_sym] the stanza method to use

# File lib/gxg/net_clients.rb, line 3411
def say(to, msg, using = :chat)
    self.write Blather::Stanza::Message.new(to, msg, using)
end
send_caps() click to toggle source

Send capabilities to the server

# File lib/gxg/net_clients.rb, line 3502
def send_caps
    if @client
        @client.register_handler :disco_info, :type => :get, :node => @client.caps.node do |s|
          r = @client.caps.dup
          r.to = s.from
          r.id = s.id
          @client.write r
        end
        @client.write client.caps.c
    end
end
send_file(the_jid=nil,the_path=nil, description=nil, buffer_size=4096, proxy=nil) click to toggle source
# File lib/gxg/net_clients.rb, line 4012
def send_file(the_jid=nil,the_path=nil, description=nil, buffer_size=4096, proxy=nil)
  if @client
    begin
      unless the_jid.is_a?(::String)
        raise ArgumentError, "You MUST supply a valid JID String to specify the recipient of the file."
      end
      unless the_path.is_a?(::String)
        raise ArgumentError, "You MUST supply a String as valid file path."
      end
      the_path = ::File.expand_path(the_path)
      unless the_path.valid_path?()
        raise ArgumentError, "You MUST supply a valid file path."
      end
      unless ::File.exist?(the_path)
        raise ArgumentError, "You MUST supply a valid file path - File does not exist."
      end
      unless description.is_a?(::String)
        description = "File Transfer: #{::File.basename(the_path)}"
      end
      unless buffer_size.is_a?(::Integer)
        raise ArgumentError, "You MUST provide an Integer to set buffer size."
      end
      valid_buffer_size_range = ::GxG::SYSTEM.maximum_buffer_size.get_at_path("/:ipv4/:tcp/:write/:valid")
      unless valid_buffer_size_range.is_a?(::Range)
        valid_buffer_size_range = (4096..65536)
      end
      unless valid_buffer_size_range.include?(buffer_size)
        raise ArgumentError, "You MUST provide an Integer between #{valid_buffer_size_range.first} and #{valid_buffer_size_range.last}."
      end
      # Review : rebuild/rewrite this section and XmppAgentFileTransfer
        #   the_transfer = ::GxG::Networking::XmppAgentFileTransfer.new(@transfer_manager, :upload, {:jid => the_jid, :path => the_path, :description => description}, this())
        #   @file_transfers_thread_safety.synchronize {
        #     @file_transfers << the_transfer
        #   }
        #   the_transfer.buffer_size = buffer_size
        #   the_transfer.upload_file(proxy)
        #   the_transfer.reference
    rescue Exception => the_error
      log_error({:error => the_error, :parameters => {:jid => the_jid, :path => the_path, :description => description, :buffer_size => buffer_size}})
    end
  else
    nil
  end
end
set_caps(node, identities, features) click to toggle source

### Set the capabilities of the client

@param [String] node the URI @param [Array<Hash>] identities an array of identities @param [Array<Hash>] features an array of features

# File lib/gxg/net_clients.rb, line 3494
def set_caps(node, identities, features)
    if @client
        @client.caps.node = node
        @client.caps.identities = identities
        @client.caps.features = features
    end
end
set_status(state = nil, msg = nil) click to toggle source

### Set current status

@param [Blather::Stanza::Presence::State::VALID_STATES] state the current state @param [#to_s] msg the status message to use

# File lib/gxg/net_clients.rb, line 3361
def set_status(state = nil, msg = nil)
    if @client
        @client.status = state, msg
    end
end
when_ready(&block) click to toggle source

### Wrapper for “handle :ready” (just a bit of syntactic sugar)

This is run after the connection has been completely setup

# File lib/gxg/net_clients.rb, line 3344
def when_ready(&block)
    self.handle :ready, &block
end
write(stanza) click to toggle source

Support Methods

# File lib/gxg/net_clients.rb, line 3289
def write(stanza)
    if @client
        @client.write stanza
    end
    true
end
write_to_stream(stanza) click to toggle source

### Write data to the stream

@param [#to_xml, to_s] stanza the data to send down the wire.

# File lib/gxg/net_clients.rb, line 3385
def write_to_stream(stanza)
    self.write stanza
end
xmpp_message_to_gxg(the_message=nil) click to toggle source

Conversion Tools

# File lib/gxg/net_clients.rb, line 3514
def xmpp_message_to_gxg(the_message=nil)
    # need: :to, :body, :state, :subject, :context, :type
    # ::Celluloid::UUID::random_generate().to_s
    unless the_message.is_a?(Blather::Stanza::Message)
      raise ArgumentError, "You MUST provide a valid message object: Blather::Stanza::Message."
    end
    gxg_message = ::GxG::Events::Message.new({:sender => :unknown})
    gxg_message[:id] = (the_message.id || ::GxG::uuid_generate.to_sym)
    gxg_message[:sender] = the_message.from.to_s
    gxg_message[:to] = the_message.to.to_s
    gxg_message[:type] = the_message.type
    if the_message.thread.is_a?(::Hash)
        gxg_message[:context] = the_message.thread.values[0]
    else
        gxg_message[:context] = the_message.thread
    end
    gxg_message[:subject] = the_message.subject
    gxg_message[:body] = the_message.body
    gxg_message
end