agent_xmpp 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/.document +5 -0
 - data/.gitignore +11 -0
 - data/LICENSE +20 -0
 - data/README.rdoc +417 -0
 - data/Rakefile +75 -0
 - data/VERSION +1 -0
 - data/agent_xmpp.gemspec +144 -0
 - data/lib/agent_xmpp.rb +22 -0
 - data/lib/agent_xmpp/admin.rb +113 -0
 - data/lib/agent_xmpp/client.rb +7 -0
 - data/lib/agent_xmpp/client/boot.rb +83 -0
 - data/lib/agent_xmpp/client/client.rb +64 -0
 - data/lib/agent_xmpp/client/connection.rb +108 -0
 - data/lib/agent_xmpp/client/controller.rb +394 -0
 - data/lib/agent_xmpp/client/message_delegate.rb +720 -0
 - data/lib/agent_xmpp/client/message_pipe.rb +193 -0
 - data/lib/agent_xmpp/client/response.rb +102 -0
 - data/lib/agent_xmpp/config.rb +48 -0
 - data/lib/agent_xmpp/main.rb +175 -0
 - data/lib/agent_xmpp/models.rb +7 -0
 - data/lib/agent_xmpp/models/contact.rb +85 -0
 - data/lib/agent_xmpp/models/message.rb +152 -0
 - data/lib/agent_xmpp/models/publication.rb +53 -0
 - data/lib/agent_xmpp/models/roster.rb +107 -0
 - data/lib/agent_xmpp/models/service.rb +91 -0
 - data/lib/agent_xmpp/models/subscription.rb +61 -0
 - data/lib/agent_xmpp/models/table_definitions.rb +107 -0
 - data/lib/agent_xmpp/patches.rb +7 -0
 - data/lib/agent_xmpp/patches/array.rb +32 -0
 - data/lib/agent_xmpp/patches/float.rb +10 -0
 - data/lib/agent_xmpp/patches/hash.rb +13 -0
 - data/lib/agent_xmpp/patches/object.rb +15 -0
 - data/lib/agent_xmpp/patches/rexml.rb +69 -0
 - data/lib/agent_xmpp/patches/string.rb +15 -0
 - data/lib/agent_xmpp/xmpp.rb +18 -0
 - data/lib/agent_xmpp/xmpp/element.rb +158 -0
 - data/lib/agent_xmpp/xmpp/entry.rb +36 -0
 - data/lib/agent_xmpp/xmpp/error_response.rb +189 -0
 - data/lib/agent_xmpp/xmpp/iq.rb +90 -0
 - data/lib/agent_xmpp/xmpp/iq_command.rb +54 -0
 - data/lib/agent_xmpp/xmpp/iq_disco.rb +206 -0
 - data/lib/agent_xmpp/xmpp/iq_pubsub.rb +270 -0
 - data/lib/agent_xmpp/xmpp/iq_roster.rb +183 -0
 - data/lib/agent_xmpp/xmpp/iq_version.rb +89 -0
 - data/lib/agent_xmpp/xmpp/jid.rb +150 -0
 - data/lib/agent_xmpp/xmpp/message.rb +82 -0
 - data/lib/agent_xmpp/xmpp/presence.rb +127 -0
 - data/lib/agent_xmpp/xmpp/sasl.rb +241 -0
 - data/lib/agent_xmpp/xmpp/stanza.rb +107 -0
 - data/lib/agent_xmpp/xmpp/x_data.rb +357 -0
 - data/test/app/app.rb +339 -0
 - data/test/cases/test_application_message_processing.rb +65 -0
 - data/test/cases/test_errors.rb +24 -0
 - data/test/cases/test_presence_management.rb +139 -0
 - data/test/cases/test_roster_management.rb +214 -0
 - data/test/cases/test_service_discovery.rb +168 -0
 - data/test/cases/test_session_management.rb +120 -0
 - data/test/cases/test_version_discovery.rb +67 -0
 - data/test/helpers/matchers.rb +23 -0
 - data/test/helpers/mocks.rb +82 -0
 - data/test/helpers/test_case_extensions.rb +45 -0
 - data/test/helpers/test_client.rb +44 -0
 - data/test/helpers/test_delegate.rb +60 -0
 - data/test/helpers/test_helper.rb +91 -0
 - data/test/messages/application_messages.rb +206 -0
 - data/test/messages/error_messages.rb +35 -0
 - data/test/messages/presence_messages.rb +66 -0
 - data/test/messages/roster_messages.rb +126 -0
 - data/test/messages/service_discovery_messages.rb +201 -0
 - data/test/messages/session_messages.rb +158 -0
 - data/test/messages/version_discovery_messages.rb +69 -0
 - data/test/peer/peer.rb +21 -0
 - metadata +187 -0
 
| 
         @@ -0,0 +1,7 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            require 'agent_xmpp/models/table_definitions'
         
     | 
| 
      
 2 
     | 
    
         
            +
            require 'agent_xmpp/models/contact'
         
     | 
| 
      
 3 
     | 
    
         
            +
            require 'agent_xmpp/models/roster'
         
     | 
| 
      
 4 
     | 
    
         
            +
            require 'agent_xmpp/models/service'
         
     | 
| 
      
 5 
     | 
    
         
            +
            require 'agent_xmpp/models/publication'
         
     | 
| 
      
 6 
     | 
    
         
            +
            require 'agent_xmpp/models/subscription'
         
     | 
| 
      
 7 
     | 
    
         
            +
            require 'agent_xmpp/models/message'
         
     | 
| 
         @@ -0,0 +1,85 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            ##############################################################################################################
         
     | 
| 
      
 2 
     | 
    
         
            +
            module AgentXmpp
         
     | 
| 
      
 3 
     | 
    
         
            +
              
         
     | 
| 
      
 4 
     | 
    
         
            +
              #####-------------------------------------------------------------------------------------------------------
         
     | 
| 
      
 5 
     | 
    
         
            +
              class Contact
         
     | 
| 
      
 6 
     | 
    
         
            +
             
     | 
| 
      
 7 
     | 
    
         
            +
                #####-------------------------------------------------------------------------------------------------------
         
     | 
| 
      
 8 
     | 
    
         
            +
                class << self
         
     | 
| 
      
 9 
     | 
    
         
            +
             
     | 
| 
      
 10 
     | 
    
         
            +
                  #.........................................................................................................
         
     | 
| 
      
 11 
     | 
    
         
            +
                  def contacts
         
     | 
| 
      
 12 
     | 
    
         
            +
                    @contacts ||= AgentXmpp.agent_xmpp_db[:contacts]
         
     | 
| 
      
 13 
     | 
    
         
            +
                  end
         
     | 
| 
      
 14 
     | 
    
         
            +
             
     | 
| 
      
 15 
     | 
    
         
            +
                  #.........................................................................................................
         
     | 
| 
      
 16 
     | 
    
         
            +
                  def load_config
         
     | 
| 
      
 17 
     | 
    
         
            +
                    if AgentXmpp.config['roster'].kind_of?(Array)
         
     | 
| 
      
 18 
     | 
    
         
            +
                      AgentXmpp.config['roster'].each {|c| update(c)}
         
     | 
| 
      
 19 
     | 
    
         
            +
                    end
         
     | 
| 
      
 20 
     | 
    
         
            +
                  end
         
     | 
| 
      
 21 
     | 
    
         
            +
             
     | 
| 
      
 22 
     | 
    
         
            +
                  #.........................................................................................................
         
     | 
| 
      
 23 
     | 
    
         
            +
                  def update(contact)
         
     | 
| 
      
 24 
     | 
    
         
            +
                    groups = contact['groups'].kind_of?(Array) ? contact['groups'].join(",") : contact['groups']
         
     | 
| 
      
 25 
     | 
    
         
            +
                    begin
         
     | 
| 
      
 26 
     | 
    
         
            +
                      contacts << {:jid => contact['jid'], :groups => groups, :subscription => 'new', :ask => 'new'}
         
     | 
| 
      
 27 
     | 
    
         
            +
                    rescue 
         
     | 
| 
      
 28 
     | 
    
         
            +
                      contacts.filter(:jid => contact['jid']).update(:groups => groups)
         
     | 
| 
      
 29 
     | 
    
         
            +
                    end
         
     | 
| 
      
 30 
     | 
    
         
            +
                  end
         
     | 
| 
      
 31 
     | 
    
         
            +
             
     | 
| 
      
 32 
     | 
    
         
            +
                  #.........................................................................................................
         
     | 
| 
      
 33 
     | 
    
         
            +
                  def update_with_roster_item(roster_item)
         
     | 
| 
      
 34 
     | 
    
         
            +
                    from_jid, subscription, ask = roster_item.jid.to_s, roster_item.subscription.to_s, roster_item.ask.to_s
         
     | 
| 
      
 35 
     | 
    
         
            +
                    contacts.filter(:jid => from_jid).update(:subscription => subscription, :ask => ask)
         
     | 
| 
      
 36 
     | 
    
         
            +
                  end
         
     | 
| 
      
 37 
     | 
    
         
            +
             
     | 
| 
      
 38 
     | 
    
         
            +
                  #.........................................................................................................
         
     | 
| 
      
 39 
     | 
    
         
            +
                  def find_all
         
     | 
| 
      
 40 
     | 
    
         
            +
                    contacts.all
         
     | 
| 
      
 41 
     | 
    
         
            +
                  end
         
     | 
| 
      
 42 
     | 
    
         
            +
             
     | 
| 
      
 43 
     | 
    
         
            +
                  #.........................................................................................................
         
     | 
| 
      
 44 
     | 
    
         
            +
                  def find_by_jid(jid)
         
     | 
| 
      
 45 
     | 
    
         
            +
                    contacts[:jid => AgentXmpp.bare_jid_to_s(jid)]
         
     | 
| 
      
 46 
     | 
    
         
            +
                  end
         
     | 
| 
      
 47 
     | 
    
         
            +
             
     | 
| 
      
 48 
     | 
    
         
            +
                  #.........................................................................................................
         
     | 
| 
      
 49 
     | 
    
         
            +
                  def find_all_by_subscription(subscription)
         
     | 
| 
      
 50 
     | 
    
         
            +
                    contacts.filter(:subscription => subscription.to_s).all
         
     | 
| 
      
 51 
     | 
    
         
            +
                  end
         
     | 
| 
      
 52 
     | 
    
         
            +
             
     | 
| 
      
 53 
     | 
    
         
            +
                  #.........................................................................................................
         
     | 
| 
      
 54 
     | 
    
         
            +
                  def has_jid?(jid)
         
     | 
| 
      
 55 
     | 
    
         
            +
                    contacts.filter(:jid => AgentXmpp.bare_jid_to_s(jid)).count > 0
         
     | 
| 
      
 56 
     | 
    
         
            +
                  end
         
     | 
| 
      
 57 
     | 
    
         
            +
             
     | 
| 
      
 58 
     | 
    
         
            +
                  #.........................................................................................................
         
     | 
| 
      
 59 
     | 
    
         
            +
                  def message_stats
         
     | 
| 
      
 60 
     | 
    
         
            +
                    find_all.map do |c|
         
     | 
| 
      
 61 
     | 
    
         
            +
                      stats = AgentXmpp.agent_xmpp_db["SELECT count(id) AS count, max(created_at) AS last FROM messages WHERE from_jid LIKE '#{c[:jid]}%'"].first
         
     | 
| 
      
 62 
     | 
    
         
            +
                      {:jid=>c[:jid], :count=>stats[:count], :last=>stats[:last].nil? ? 'Never' : Time.parse(stats[:last]).strftime("%y/%m/%d %H:%M")}
         
     | 
| 
      
 63 
     | 
    
         
            +
                    end        
         
     | 
| 
      
 64 
     | 
    
         
            +
                  end
         
     | 
| 
      
 65 
     | 
    
         
            +
                  
         
     | 
| 
      
 66 
     | 
    
         
            +
                  #.........................................................................................................
         
     | 
| 
      
 67 
     | 
    
         
            +
                  def destroy_by_jid(jid)
         
     | 
| 
      
 68 
     | 
    
         
            +
                    contact = contacts.filter(:jid => AgentXmpp.bare_jid_to_s(jid))
         
     | 
| 
      
 69 
     | 
    
         
            +
                    Roster.destroy_by_contact_id(contact.first[:id])
         
     | 
| 
      
 70 
     | 
    
         
            +
                    contact.delete
         
     | 
| 
      
 71 
     | 
    
         
            +
                  end 
         
     | 
| 
      
 72 
     | 
    
         
            +
             
     | 
| 
      
 73 
     | 
    
         
            +
                  #.........................................................................................................
         
     | 
| 
      
 74 
     | 
    
         
            +
                  def method_missing(meth, *args, &blk)
         
     | 
| 
      
 75 
     | 
    
         
            +
                    contacts.send(meth, *args, &blk)
         
     | 
| 
      
 76 
     | 
    
         
            +
                  end
         
     | 
| 
      
 77 
     | 
    
         
            +
                  
         
     | 
| 
      
 78 
     | 
    
         
            +
                #### self
         
     | 
| 
      
 79 
     | 
    
         
            +
                end
         
     | 
| 
      
 80 
     | 
    
         
            +
             
     | 
| 
      
 81 
     | 
    
         
            +
              #### Contact
         
     | 
| 
      
 82 
     | 
    
         
            +
              end
         
     | 
| 
      
 83 
     | 
    
         
            +
             
     | 
| 
      
 84 
     | 
    
         
            +
            #### AgentXmpp
         
     | 
| 
      
 85 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -0,0 +1,152 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            ##############################################################################################################
         
     | 
| 
      
 2 
     | 
    
         
            +
            module AgentXmpp
         
     | 
| 
      
 3 
     | 
    
         
            +
              
         
     | 
| 
      
 4 
     | 
    
         
            +
              #####-------------------------------------------------------------------------------------------------------
         
     | 
| 
      
 5 
     | 
    
         
            +
              class Message
         
     | 
| 
      
 6 
     | 
    
         
            +
             
     | 
| 
      
 7 
     | 
    
         
            +
                #####-------------------------------------------------------------------------------------------------------
         
     | 
| 
      
 8 
     | 
    
         
            +
                class << self
         
     | 
| 
      
 9 
     | 
    
         
            +
             
     | 
| 
      
 10 
     | 
    
         
            +
                  #.........................................................................................................
         
     | 
| 
      
 11 
     | 
    
         
            +
                  def messages(renew=false)
         
     | 
| 
      
 12 
     | 
    
         
            +
                    @messages ||= AgentXmpp.agent_xmpp_db[:messages]
         
     | 
| 
      
 13 
     | 
    
         
            +
                  end
         
     | 
| 
      
 14 
     | 
    
         
            +
             
     | 
| 
      
 15 
     | 
    
         
            +
                  #.........................................................................................................
         
     | 
| 
      
 16 
     | 
    
         
            +
                  def update(stanza)
         
     | 
| 
      
 17 
     | 
    
         
            +
                    case stanza
         
     | 
| 
      
 18 
     | 
    
         
            +
                      when AgentXmpp::Xmpp::Message 
         
     | 
| 
      
 19 
     | 
    
         
            +
                        if stanza.type.eql?(:chat)
         
     | 
| 
      
 20 
     | 
    
         
            +
                          update_with_chat_message(stanza)
         
     | 
| 
      
 21 
     | 
    
         
            +
                        end
         
     | 
| 
      
 22 
     | 
    
         
            +
                      when AgentXmpp::Xmpp::Iq
         
     | 
| 
      
 23 
     | 
    
         
            +
                        if cmd = stanza.command
         
     | 
| 
      
 24 
     | 
    
         
            +
                          if data = cmd.x
         
     | 
| 
      
 25 
     | 
    
         
            +
                            update_with_command_data(stanza, data, cmd.node)
         
     | 
| 
      
 26 
     | 
    
         
            +
                          else
         
     | 
| 
      
 27 
     | 
    
         
            +
                            update_with_command_request(stanza, cmd.node)
         
     | 
| 
      
 28 
     | 
    
         
            +
                          end
         
     | 
| 
      
 29 
     | 
    
         
            +
                        elsif (pubsub = stanza.pubsub).kind_of?(AgentXmpp::Xmpp::IqPubSub) and pub = pubsub.publish and item = pub.item 
         
     | 
| 
      
 30 
     | 
    
         
            +
                          if data = item.x
         
     | 
| 
      
 31 
     | 
    
         
            +
                            update_with_published_data(stanza, data, pub.node)
         
     | 
| 
      
 32 
     | 
    
         
            +
                          end
         
     | 
| 
      
 33 
     | 
    
         
            +
                        end
         
     | 
| 
      
 34 
     | 
    
         
            +
                    end                 
         
     | 
| 
      
 35 
     | 
    
         
            +
                  end
         
     | 
| 
      
 36 
     | 
    
         
            +
             
     | 
| 
      
 37 
     | 
    
         
            +
                  #.........................................................................................................
         
     | 
| 
      
 38 
     | 
    
         
            +
                  def update_received_event_item(item, from, node)
         
     | 
| 
      
 39 
     | 
    
         
            +
                    (event_item =  item.entry || item.x) if item.respond_to?(:entry) and item.respond_to?(:x)
         
     | 
| 
      
 40 
     | 
    
         
            +
                    event_item.nil? ? false : update_with_event_item(event_item, from, node, item.id) 
         
     | 
| 
      
 41 
     | 
    
         
            +
                  end
         
     | 
| 
      
 42 
     | 
    
         
            +
             
     | 
| 
      
 43 
     | 
    
         
            +
                  #.........................................................................................................
         
     | 
| 
      
 44 
     | 
    
         
            +
                  def find_by_item_id(item_id)
         
     | 
| 
      
 45 
     | 
    
         
            +
                    item_id.nil? ? nil : messages[:item_id => item_id]        
         
     | 
| 
      
 46 
     | 
    
         
            +
                  end
         
     | 
| 
      
 47 
     | 
    
         
            +
             
     | 
| 
      
 48 
     | 
    
         
            +
                  #.........................................................................................................
         
     | 
| 
      
 49 
     | 
    
         
            +
                  def count_by_from_jid(from_jid)
         
     | 
| 
      
 50 
     | 
    
         
            +
                  end
         
     | 
| 
      
 51 
     | 
    
         
            +
             
     | 
| 
      
 52 
     | 
    
         
            +
                  #.........................................................................................................
         
     | 
| 
      
 53 
     | 
    
         
            +
                  def count_by_content_type(content_type)
         
     | 
| 
      
 54 
     | 
    
         
            +
                    messages.filter(:content_type => content_type).count
         
     | 
| 
      
 55 
     | 
    
         
            +
                  end
         
     | 
| 
      
 56 
     | 
    
         
            +
             
     | 
| 
      
 57 
     | 
    
         
            +
                  #.........................................................................................................
         
     | 
| 
      
 58 
     | 
    
         
            +
                  def stats_by_message_type
         
     | 
| 
      
 59 
     | 
    
         
            +
                    AgentXmpp.agent_xmpp_db['SELECT message_type AS type, count(id) AS count, max(created_at) AS last FROM messages GROUP BY message_type'].all.map do |s|
         
     | 
| 
      
 60 
     | 
    
         
            +
                      {:type=>s[:type], :count=>s[:count], :last=>Time.parse(s[:last]).strftime("%y/%m/%d %H:%M")}
         
     | 
| 
      
 61 
     | 
    
         
            +
                    end        
         
     | 
| 
      
 62 
     | 
    
         
            +
                  end
         
     | 
| 
      
 63 
     | 
    
         
            +
                    
         
     | 
| 
      
 64 
     | 
    
         
            +
                  #.........................................................................................................
         
     | 
| 
      
 65 
     | 
    
         
            +
                  def stats_by_node(node)
         
     | 
| 
      
 66 
     | 
    
         
            +
                    stats = AgentXmpp.agent_xmpp_db["SELECT node, count(id) AS count, max(created_at) AS last FROM messages WHERE node = ?", node].first
         
     | 
| 
      
 67 
     | 
    
         
            +
                    {:node=>node, :count=>stats[:count], :last=>stats[:last].nil? ? 'Never' : Time.parse(stats[:last]).strftime("%y/%m/%d %H:%M")}
         
     | 
| 
      
 68 
     | 
    
         
            +
                  end
         
     | 
| 
      
 69 
     | 
    
         
            +
                            
         
     | 
| 
      
 70 
     | 
    
         
            +
                  #.........................................................................................................
         
     | 
| 
      
 71 
     | 
    
         
            +
                  def stats_by_command_node
         
     | 
| 
      
 72 
     | 
    
         
            +
                    BaseController.command_nodes.map{|n| stats_by_node(n)}        
         
     | 
| 
      
 73 
     | 
    
         
            +
                  end
         
     | 
| 
      
 74 
     | 
    
         
            +
                            
         
     | 
| 
      
 75 
     | 
    
         
            +
                  #.........................................................................................................
         
     | 
| 
      
 76 
     | 
    
         
            +
                  # private
         
     | 
| 
      
 77 
     | 
    
         
            +
                  #.........................................................................................................
         
     | 
| 
      
 78 
     | 
    
         
            +
                  def update_with_chat_message(stanza)
         
     | 
| 
      
 79 
     | 
    
         
            +
                    from_jid = stanza.from || AgentXmpp.jid 
         
     | 
| 
      
 80 
     | 
    
         
            +
                    messages << {
         
     | 
| 
      
 81 
     | 
    
         
            +
                      :message_text => stanza.body,
         
     | 
| 
      
 82 
     | 
    
         
            +
                      :content_type => 'text',
         
     | 
| 
      
 83 
     | 
    
         
            +
                      :message_type => 'chat',
         
     | 
| 
      
 84 
     | 
    
         
            +
                      :to_jid       => stanza.to.to_s,
         
     | 
| 
      
 85 
     | 
    
         
            +
                      :from_jid     => from_jid.to_s,
         
     | 
| 
      
 86 
     | 
    
         
            +
                      :created_at   => Time.now}
         
     | 
| 
      
 87 
     | 
    
         
            +
                  end
         
     | 
| 
      
 88 
     | 
    
         
            +
             
         
     | 
| 
      
 89 
     | 
    
         
            +
                  #.........................................................................................................
         
     | 
| 
      
 90 
     | 
    
         
            +
                  def update_with_command_request(stanza, node)
         
     | 
| 
      
 91 
     | 
    
         
            +
                    from_jid = stanza.from || AgentXmpp.jid 
         
     | 
| 
      
 92 
     | 
    
         
            +
                    messages << {
         
     | 
| 
      
 93 
     | 
    
         
            +
                      :content_type  => 'command_request',
         
     | 
| 
      
 94 
     | 
    
         
            +
                      :message_type   => 'command',
         
     | 
| 
      
 95 
     | 
    
         
            +
                      :to_jid        => stanza.to.to_s,
         
     | 
| 
      
 96 
     | 
    
         
            +
                      :from_jid      => from_jid.to_s,
         
     | 
| 
      
 97 
     | 
    
         
            +
                      :node          => node,
         
     | 
| 
      
 98 
     | 
    
         
            +
                      :created_at    => Time.now}
         
     | 
| 
      
 99 
     | 
    
         
            +
                  end
         
     | 
| 
      
 100 
     | 
    
         
            +
             
     | 
| 
      
 101 
     | 
    
         
            +
                  #.........................................................................................................
         
     | 
| 
      
 102 
     | 
    
         
            +
                  def update_with_command_data(stanza, data, node)
         
     | 
| 
      
 103 
     | 
    
         
            +
                    from_jid = stanza.from || AgentXmpp.jid 
         
     | 
| 
      
 104 
     | 
    
         
            +
                    messages << {
         
     | 
| 
      
 105 
     | 
    
         
            +
                      :message_text  => data.to_s,
         
     | 
| 
      
 106 
     | 
    
         
            +
                      :content_type  => 'x',
         
     | 
| 
      
 107 
     | 
    
         
            +
                      :message_type  => 'command',
         
     | 
| 
      
 108 
     | 
    
         
            +
                      :to_jid        => stanza.to.to_s,
         
     | 
| 
      
 109 
     | 
    
         
            +
                      :from_jid      => from_jid.to_s,
         
     | 
| 
      
 110 
     | 
    
         
            +
                      :node          => node,
         
     | 
| 
      
 111 
     | 
    
         
            +
                      :created_at    => Time.now}
         
     | 
| 
      
 112 
     | 
    
         
            +
                  end
         
     | 
| 
      
 113 
     | 
    
         
            +
             
         
     | 
| 
      
 114 
     | 
    
         
            +
                  #.........................................................................................................
         
     | 
| 
      
 115 
     | 
    
         
            +
                  def update_with_published_data(stanza, data, node)
         
     | 
| 
      
 116 
     | 
    
         
            +
                    from_jid = stanza.from || AgentXmpp.jid 
         
     | 
| 
      
 117 
     | 
    
         
            +
                    messages << {
         
     | 
| 
      
 118 
     | 
    
         
            +
                      :message_text  => data.to_s,
         
     | 
| 
      
 119 
     | 
    
         
            +
                      :content_type  => 'x',
         
     | 
| 
      
 120 
     | 
    
         
            +
                      :message_type  => 'event',
         
     | 
| 
      
 121 
     | 
    
         
            +
                      :to_jid        => stanza.to.to_s,
         
     | 
| 
      
 122 
     | 
    
         
            +
                      :from_jid      => from_jid.to_s,
         
     | 
| 
      
 123 
     | 
    
         
            +
                      :node          => node,
         
     | 
| 
      
 124 
     | 
    
         
            +
                      :created_at    => Time.now}
         
     | 
| 
      
 125 
     | 
    
         
            +
                  end
         
     | 
| 
      
 126 
     | 
    
         
            +
             
     | 
| 
      
 127 
     | 
    
         
            +
                  #.........................................................................................................
         
     | 
| 
      
 128 
     | 
    
         
            +
                  def update_with_event_item(event_item, from, node, item_id)
         
     | 
| 
      
 129 
     | 
    
         
            +
                    unless find_by_item_id(item_id)
         
     | 
| 
      
 130 
     | 
    
         
            +
                      messages << {
         
     | 
| 
      
 131 
     | 
    
         
            +
                        :message_text  => event_item.to_s,
         
     | 
| 
      
 132 
     | 
    
         
            +
                        :content_type  => event_item.name,
         
     | 
| 
      
 133 
     | 
    
         
            +
                        :message_type  => 'event',
         
     | 
| 
      
 134 
     | 
    
         
            +
                        :to_jid        => AgentXmpp.jid.to_s,
         
     | 
| 
      
 135 
     | 
    
         
            +
                        :from_jid      => from.to_s,
         
     | 
| 
      
 136 
     | 
    
         
            +
                        :node          => node,
         
     | 
| 
      
 137 
     | 
    
         
            +
                        :item_id       => item_id,
         
     | 
| 
      
 138 
     | 
    
         
            +
                        :created_at    => Time.now}; true
         
     | 
| 
      
 139 
     | 
    
         
            +
                    else; false; end    
         
     | 
| 
      
 140 
     | 
    
         
            +
                  end
         
     | 
| 
      
 141 
     | 
    
         
            +
                   
         
     | 
| 
      
 142 
     | 
    
         
            +
                  #.........................................................................................................
         
     | 
| 
      
 143 
     | 
    
         
            +
                  private :update_with_chat_message, :update_with_command_data, :update_with_published_data, :update_with_command_request
         
     | 
| 
      
 144 
     | 
    
         
            +
             
     | 
| 
      
 145 
     | 
    
         
            +
                #### self
         
     | 
| 
      
 146 
     | 
    
         
            +
                end
         
     | 
| 
      
 147 
     | 
    
         
            +
             
     | 
| 
      
 148 
     | 
    
         
            +
              #### Message
         
     | 
| 
      
 149 
     | 
    
         
            +
              end
         
     | 
| 
      
 150 
     | 
    
         
            +
             
     | 
| 
      
 151 
     | 
    
         
            +
            #### AgentXmpp
         
     | 
| 
      
 152 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -0,0 +1,53 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            ##############################################################################################################
         
     | 
| 
      
 2 
     | 
    
         
            +
            module AgentXmpp
         
     | 
| 
      
 3 
     | 
    
         
            +
              
         
     | 
| 
      
 4 
     | 
    
         
            +
              #####-------------------------------------------------------------------------------------------------------
         
     | 
| 
      
 5 
     | 
    
         
            +
              class Publication
         
     | 
| 
      
 6 
     | 
    
         
            +
             
     | 
| 
      
 7 
     | 
    
         
            +
                #####-------------------------------------------------------------------------------------------------------
         
     | 
| 
      
 8 
     | 
    
         
            +
                class << self
         
     | 
| 
      
 9 
     | 
    
         
            +
             
     | 
| 
      
 10 
     | 
    
         
            +
                  #.........................................................................................................
         
     | 
| 
      
 11 
     | 
    
         
            +
                  def publications(renew=false)
         
     | 
| 
      
 12 
     | 
    
         
            +
                    @publications ||= AgentXmpp.in_memory_db[:publications]
         
     | 
| 
      
 13 
     | 
    
         
            +
                  end
         
     | 
| 
      
 14 
     | 
    
         
            +
             
     | 
| 
      
 15 
     | 
    
         
            +
                  #.........................................................................................................
         
     | 
| 
      
 16 
     | 
    
         
            +
                  def load_config
         
     | 
| 
      
 17 
     | 
    
         
            +
                    if AgentXmpp.config['publish'].kind_of?(Array)
         
     | 
| 
      
 18 
     | 
    
         
            +
                      AgentXmpp.config['publish'].each do |pub|
         
     | 
| 
      
 19 
     | 
    
         
            +
                        publications << AgentXmpp::DEFAULT_PUBSUB_CONFIG.inject({}) do |f, (a, v)| 
         
     | 
| 
      
 20 
     | 
    
         
            +
                          f.merge(a => pub[a.to_s] || v)
         
     | 
| 
      
 21 
     | 
    
         
            +
                        end.merge(:status => 'new', :node => pub['node']) 
         
     | 
| 
      
 22 
     | 
    
         
            +
                      end
         
     | 
| 
      
 23 
     | 
    
         
            +
                    end
         
     | 
| 
      
 24 
     | 
    
         
            +
                  end
         
     | 
| 
      
 25 
     | 
    
         
            +
             
     | 
| 
      
 26 
     | 
    
         
            +
                  #.........................................................................................................
         
     | 
| 
      
 27 
     | 
    
         
            +
                  def find_by_node(node)
         
     | 
| 
      
 28 
     | 
    
         
            +
                    publications[:node => node]
         
     | 
| 
      
 29 
     | 
    
         
            +
                  end
         
     | 
| 
      
 30 
     | 
    
         
            +
             
     | 
| 
      
 31 
     | 
    
         
            +
                  #.........................................................................................................
         
     | 
| 
      
 32 
     | 
    
         
            +
                  def find_all
         
     | 
| 
      
 33 
     | 
    
         
            +
                    publications.all
         
     | 
| 
      
 34 
     | 
    
         
            +
                  end
         
     | 
| 
      
 35 
     | 
    
         
            +
             
     | 
| 
      
 36 
     | 
    
         
            +
                  #.........................................................................................................
         
     | 
| 
      
 37 
     | 
    
         
            +
                  def update_status(node, status)
         
     | 
| 
      
 38 
     | 
    
         
            +
                    publications.filter(:node => node).update(:status => status.to_s)
         
     | 
| 
      
 39 
     | 
    
         
            +
                  end
         
     | 
| 
      
 40 
     | 
    
         
            +
             
     | 
| 
      
 41 
     | 
    
         
            +
                  #.........................................................................................................
         
     | 
| 
      
 42 
     | 
    
         
            +
                  def stats_by_node
         
     | 
| 
      
 43 
     | 
    
         
            +
                    find_all.map{|p| Message.stats_by_node("#{AgentXmpp.user_pubsub_root}/#{p[:node]}").update(:node=>p[:node].split('/').last)}
         
     | 
| 
      
 44 
     | 
    
         
            +
                  end
         
     | 
| 
      
 45 
     | 
    
         
            +
                  
         
     | 
| 
      
 46 
     | 
    
         
            +
                #### self
         
     | 
| 
      
 47 
     | 
    
         
            +
                end
         
     | 
| 
      
 48 
     | 
    
         
            +
             
     | 
| 
      
 49 
     | 
    
         
            +
              #### Publication
         
     | 
| 
      
 50 
     | 
    
         
            +
              end
         
     | 
| 
      
 51 
     | 
    
         
            +
             
     | 
| 
      
 52 
     | 
    
         
            +
            #### AgentXmpp
         
     | 
| 
      
 53 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -0,0 +1,107 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            ##############################################################################################################
         
     | 
| 
      
 2 
     | 
    
         
            +
            module AgentXmpp
         
     | 
| 
      
 3 
     | 
    
         
            +
                
         
     | 
| 
      
 4 
     | 
    
         
            +
              #####-------------------------------------------------------------------------------------------------------
         
     | 
| 
      
 5 
     | 
    
         
            +
              class Roster
         
     | 
| 
      
 6 
     | 
    
         
            +
             
     | 
| 
      
 7 
     | 
    
         
            +
                #####-------------------------------------------------------------------------------------------------------
         
     | 
| 
      
 8 
     | 
    
         
            +
                class << self
         
     | 
| 
      
 9 
     | 
    
         
            +
             
     | 
| 
      
 10 
     | 
    
         
            +
                  #.........................................................................................................
         
     | 
| 
      
 11 
     | 
    
         
            +
                  def roster(renew=false)
         
     | 
| 
      
 12 
     | 
    
         
            +
                    @roster ||= AgentXmpp.in_memory_db[:roster]
         
     | 
| 
      
 13 
     | 
    
         
            +
                  end
         
     | 
| 
      
 14 
     | 
    
         
            +
             
     | 
| 
      
 15 
     | 
    
         
            +
                  #.........................................................................................................
         
     | 
| 
      
 16 
     | 
    
         
            +
                  def update(msg, from=nil)
         
     | 
| 
      
 17 
     | 
    
         
            +
                    case msg
         
     | 
| 
      
 18 
     | 
    
         
            +
                      when AgentXmpp::Xmpp::Presence then update_with_presence(msg)
         
     | 
| 
      
 19 
     | 
    
         
            +
                      when AgentXmpp::Xmpp::IqVersion then update_with_version(msg, from)
         
     | 
| 
      
 20 
     | 
    
         
            +
                     end                 
         
     | 
| 
      
 21 
     | 
    
         
            +
                  end
         
     | 
| 
      
 22 
     | 
    
         
            +
             
         
     | 
| 
      
 23 
     | 
    
         
            +
                  #.........................................................................................................
         
     | 
| 
      
 24 
     | 
    
         
            +
                  def update_status(jid, status)
         
     | 
| 
      
 25 
     | 
    
         
            +
                    roster.filter(:jid => AgentXmpp.full_jid_to_s(jid)).update(:status => status.to_s)
         
     | 
| 
      
 26 
     | 
    
         
            +
                  end
         
     | 
| 
      
 27 
     | 
    
         
            +
                            
         
     | 
| 
      
 28 
     | 
    
         
            +
                  #.........................................................................................................
         
     | 
| 
      
 29 
     | 
    
         
            +
                  def find_all
         
     | 
| 
      
 30 
     | 
    
         
            +
                    roster.all  
         
     | 
| 
      
 31 
     | 
    
         
            +
                  end
         
     | 
| 
      
 32 
     | 
    
         
            +
             
     | 
| 
      
 33 
     | 
    
         
            +
                  #.........................................................................................................
         
     | 
| 
      
 34 
     | 
    
         
            +
                  def find_by_jid(jid)
         
     | 
| 
      
 35 
     | 
    
         
            +
                    roster[:jid => AgentXmpp.full_jid_to_s(jid)]
         
     | 
| 
      
 36 
     | 
    
         
            +
                  end 
         
     | 
| 
      
 37 
     | 
    
         
            +
                  
         
     | 
| 
      
 38 
     | 
    
         
            +
                  #.........................................................................................................
         
     | 
| 
      
 39 
     | 
    
         
            +
                  def find_all_by_status(status)
         
     | 
| 
      
 40 
     | 
    
         
            +
                    roster.filter(:status => status.to_s).all
         
     | 
| 
      
 41 
     | 
    
         
            +
                  end
         
     | 
| 
      
 42 
     | 
    
         
            +
             
     | 
| 
      
 43 
     | 
    
         
            +
                  #.........................................................................................................
         
     | 
| 
      
 44 
     | 
    
         
            +
                  def find_all_by_contact_jid(jid)
         
     | 
| 
      
 45 
     | 
    
         
            +
                    if contact = Contact.find_by_jid(jid)
         
     | 
| 
      
 46 
     | 
    
         
            +
                      roster.filter(:contact_id => contact[:contact_id]).all
         
     | 
| 
      
 47 
     | 
    
         
            +
                    else; []; end
         
     | 
| 
      
 48 
     | 
    
         
            +
                  end 
         
     | 
| 
      
 49 
     | 
    
         
            +
                  
         
     | 
| 
      
 50 
     | 
    
         
            +
                  #.........................................................................................................
         
     | 
| 
      
 51 
     | 
    
         
            +
                  def find_all_by_contact_jid_and_status(jid, status)
         
     | 
| 
      
 52 
     | 
    
         
            +
                    if contact = Contact.find_by_jid(jid)
         
     | 
| 
      
 53 
     | 
    
         
            +
                      roster.filter(:contact_id => contact[:id]).all
         
     | 
| 
      
 54 
     | 
    
         
            +
                    else; []; end
         
     | 
| 
      
 55 
     | 
    
         
            +
                  end 
         
     | 
| 
      
 56 
     | 
    
         
            +
                  
         
     | 
| 
      
 57 
     | 
    
         
            +
                  #.........................................................................................................
         
     | 
| 
      
 58 
     | 
    
         
            +
                  def destroy_by_contact_id(contact_id)
         
     | 
| 
      
 59 
     | 
    
         
            +
                    roster.filter(:contact_id => contact_id).delete
         
     | 
| 
      
 60 
     | 
    
         
            +
                  end 
         
     | 
| 
      
 61 
     | 
    
         
            +
             
     | 
| 
      
 62 
     | 
    
         
            +
                  #.........................................................................................................
         
     | 
| 
      
 63 
     | 
    
         
            +
                  def has_version?(jid)
         
     | 
| 
      
 64 
     | 
    
         
            +
                    if item = find_by_jid(jid)
         
     | 
| 
      
 65 
     | 
    
         
            +
                      not (item[:client_name].nil? or item[:client_version].nil?)
         
     | 
| 
      
 66 
     | 
    
         
            +
                    else; false; end
         
     | 
| 
      
 67 
     | 
    
         
            +
                  end 
         
     | 
| 
      
 68 
     | 
    
         
            +
             
     | 
| 
      
 69 
     | 
    
         
            +
                  #.........................................................................................................
         
     | 
| 
      
 70 
     | 
    
         
            +
                  def method_missing(meth, *args, &blk)
         
     | 
| 
      
 71 
     | 
    
         
            +
                    roster.send(meth, *args, &blk)
         
     | 
| 
      
 72 
     | 
    
         
            +
                  end
         
     | 
| 
      
 73 
     | 
    
         
            +
             
     | 
| 
      
 74 
     | 
    
         
            +
                  #.........................................................................................................
         
     | 
| 
      
 75 
     | 
    
         
            +
                  # private
         
     | 
| 
      
 76 
     | 
    
         
            +
                  #.........................................................................................................
         
     | 
| 
      
 77 
     | 
    
         
            +
                  def update_with_presence(presence)
         
     | 
| 
      
 78 
     | 
    
         
            +
                    from_jid = presence.from.to_s    
         
     | 
| 
      
 79 
     | 
    
         
            +
                    contact = Contact.find_by_jid(presence.from)
         
     | 
| 
      
 80 
     | 
    
         
            +
                    status = presence.type.nil? ? 'available' : presence.type.to_s 
         
     | 
| 
      
 81 
     | 
    
         
            +
                    if (contact)
         
     | 
| 
      
 82 
     | 
    
         
            +
                      begin
         
     | 
| 
      
 83 
     | 
    
         
            +
                        roster << {:jid => from_jid, :status => status, :contact_id => contact[:id]}
         
     | 
| 
      
 84 
     | 
    
         
            +
                      rescue 
         
     | 
| 
      
 85 
     | 
    
         
            +
                        roster.filter(:jid => from_jid).update(:status => status)
         
     | 
| 
      
 86 
     | 
    
         
            +
                      end
         
     | 
| 
      
 87 
     | 
    
         
            +
                    end
         
     | 
| 
      
 88 
     | 
    
         
            +
                  end
         
     | 
| 
      
 89 
     | 
    
         
            +
             
     | 
| 
      
 90 
     | 
    
         
            +
                  #.........................................................................................................
         
     | 
| 
      
 91 
     | 
    
         
            +
                  def update_with_version(vquery, from)
         
     | 
| 
      
 92 
     | 
    
         
            +
                    if (item = roster.filter(:jid => from.to_s))  
         
     | 
| 
      
 93 
     | 
    
         
            +
                      item.update(:client_name => vquery.iname, :client_version => vquery.version, :client_os => vquery.os)
         
     | 
| 
      
 94 
     | 
    
         
            +
                    end
         
     | 
| 
      
 95 
     | 
    
         
            +
                  end
         
     | 
| 
      
 96 
     | 
    
         
            +
                  
         
     | 
| 
      
 97 
     | 
    
         
            +
                  #.........................................................................................................
         
     | 
| 
      
 98 
     | 
    
         
            +
                  private :update_with_presence, :update_with_version
         
     | 
| 
      
 99 
     | 
    
         
            +
             
     | 
| 
      
 100 
     | 
    
         
            +
                #### self
         
     | 
| 
      
 101 
     | 
    
         
            +
                end
         
     | 
| 
      
 102 
     | 
    
         
            +
             
     | 
| 
      
 103 
     | 
    
         
            +
              #### Roster
         
     | 
| 
      
 104 
     | 
    
         
            +
              end
         
     | 
| 
      
 105 
     | 
    
         
            +
             
     | 
| 
      
 106 
     | 
    
         
            +
            #### AgentXmpp
         
     | 
| 
      
 107 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -0,0 +1,91 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            ##############################################################################################################
         
     | 
| 
      
 2 
     | 
    
         
            +
            module AgentXmpp
         
     | 
| 
      
 3 
     | 
    
         
            +
              
         
     | 
| 
      
 4 
     | 
    
         
            +
              #####-------------------------------------------------------------------------------------------------------
         
     | 
| 
      
 5 
     | 
    
         
            +
              class Service
         
     | 
| 
      
 6 
     | 
    
         
            +
             
     | 
| 
      
 7 
     | 
    
         
            +
                #####-------------------------------------------------------------------------------------------------------
         
     | 
| 
      
 8 
     | 
    
         
            +
                class << self
         
     | 
| 
      
 9 
     | 
    
         
            +
             
     | 
| 
      
 10 
     | 
    
         
            +
                  #.........................................................................................................
         
     | 
| 
      
 11 
     | 
    
         
            +
                  def services(renew=false)
         
     | 
| 
      
 12 
     | 
    
         
            +
                    @services ||= AgentXmpp.in_memory_db[:services]
         
     | 
| 
      
 13 
     | 
    
         
            +
                  end
         
     | 
| 
      
 14 
     | 
    
         
            +
             
     | 
| 
      
 15 
     | 
    
         
            +
                  #.........................................................................................................
         
     | 
| 
      
 16 
     | 
    
         
            +
                  def service_items
         
     | 
| 
      
 17 
     | 
    
         
            +
                    @service_items ||= AgentXmpp.in_memory_db[:service_items]
         
     | 
| 
      
 18 
     | 
    
         
            +
                  end
         
     | 
| 
      
 19 
     | 
    
         
            +
             
     | 
| 
      
 20 
     | 
    
         
            +
                  #.........................................................................................................
         
     | 
| 
      
 21 
     | 
    
         
            +
                  def service_features
         
     | 
| 
      
 22 
     | 
    
         
            +
                    @service_features ||= AgentXmpp.in_memory_db[:service_features]
         
     | 
| 
      
 23 
     | 
    
         
            +
                  end
         
     | 
| 
      
 24 
     | 
    
         
            +
             
     | 
| 
      
 25 
     | 
    
         
            +
                  #.........................................................................................................
         
     | 
| 
      
 26 
     | 
    
         
            +
                  def update(disco_iq)
         
     | 
| 
      
 27 
     | 
    
         
            +
                    disco = disco_iq.query
         
     | 
| 
      
 28 
     | 
    
         
            +
                    case disco
         
     | 
| 
      
 29 
     | 
    
         
            +
                      when AgentXmpp::Xmpp::IqDiscoInfo then update_with_disco_info(disco_iq)
         
     | 
| 
      
 30 
     | 
    
         
            +
                      when AgentXmpp::Xmpp::IqDiscoItems then update_with_disco_items(disco_iq)
         
     | 
| 
      
 31 
     | 
    
         
            +
                    end
         
     | 
| 
      
 32 
     | 
    
         
            +
                  end
         
     | 
| 
      
 33 
     | 
    
         
            +
             
     | 
| 
      
 34 
     | 
    
         
            +
                  #.........................................................................................................
         
     | 
| 
      
 35 
     | 
    
         
            +
                  def has_jid?(jid)
         
     | 
| 
      
 36 
     | 
    
         
            +
                    services.filter(:jid => jid.to_s).count > 0
         
     | 
| 
      
 37 
     | 
    
         
            +
                  end
         
     | 
| 
      
 38 
     | 
    
         
            +
             
     | 
| 
      
 39 
     | 
    
         
            +
                  #.........................................................................................................
         
     | 
| 
      
 40 
     | 
    
         
            +
                  def has_disco_info?(jid)
         
     | 
| 
      
 41 
     | 
    
         
            +
                    services.filter(:jid => jid.to_s).count > 0
         
     | 
| 
      
 42 
     | 
    
         
            +
                  end
         
     | 
| 
      
 43 
     | 
    
         
            +
             
     | 
| 
      
 44 
     | 
    
         
            +
                  #.........................................................................................................
         
     | 
| 
      
 45 
     | 
    
         
            +
                  def has_disco_items?(jid)
         
     | 
| 
      
 46 
     | 
    
         
            +
                    service_items.filter(:service => jid.to_s).count > 0
         
     | 
| 
      
 47 
     | 
    
         
            +
                  end
         
     | 
| 
      
 48 
     | 
    
         
            +
             
     | 
| 
      
 49 
     | 
    
         
            +
                  #.........................................................................................................
         
     | 
| 
      
 50 
     | 
    
         
            +
                  # private
         
     | 
| 
      
 51 
     | 
    
         
            +
                  #.........................................................................................................
         
     | 
| 
      
 52 
     | 
    
         
            +
                  def update_with_disco_info(disco_iq)
         
     | 
| 
      
 53 
     | 
    
         
            +
                    disco, service = disco_iq.query, disco_iq.from.to_s
         
     | 
| 
      
 54 
     | 
    
         
            +
                    node = disco.node
         
     | 
| 
      
 55 
     | 
    
         
            +
                    disco.identities.each do |i|
         
     | 
| 
      
 56 
     | 
    
         
            +
                      begin
         
     | 
| 
      
 57 
     | 
    
         
            +
                        services << {:node => node, :jid => service, :category => i.category, :type => i.type, :name => i.iname}
         
     | 
| 
      
 58 
     | 
    
         
            +
                      rescue
         
     | 
| 
      
 59 
     | 
    
         
            +
                      end
         
     | 
| 
      
 60 
     | 
    
         
            +
                    end
         
     | 
| 
      
 61 
     | 
    
         
            +
                    disco.features.each do |f|
         
     | 
| 
      
 62 
     | 
    
         
            +
                      begin
         
     | 
| 
      
 63 
     | 
    
         
            +
                        service_features << {:node => node, :service => service, :var => f.var}
         
     | 
| 
      
 64 
     | 
    
         
            +
                      rescue
         
     | 
| 
      
 65 
     | 
    
         
            +
                      end
         
     | 
| 
      
 66 
     | 
    
         
            +
                    end
         
     | 
| 
      
 67 
     | 
    
         
            +
                  end
         
     | 
| 
      
 68 
     | 
    
         
            +
             
     | 
| 
      
 69 
     | 
    
         
            +
                  #.........................................................................................................
         
     | 
| 
      
 70 
     | 
    
         
            +
                  def update_with_disco_items(disco_iq)
         
     | 
| 
      
 71 
     | 
    
         
            +
                    disco, service = disco_iq.query, disco_iq.from.to_s
         
     | 
| 
      
 72 
     | 
    
         
            +
                    parent_node = disco.node
         
     | 
| 
      
 73 
     | 
    
         
            +
                    disco.items.each do |i|
         
     | 
| 
      
 74 
     | 
    
         
            +
                      begin
         
     | 
| 
      
 75 
     | 
    
         
            +
                        service_items << {:parent_node => parent_node, :service => service, :node => i.node, :jid => i.jid.to_s, :name => i.iname}
         
     | 
| 
      
 76 
     | 
    
         
            +
                      rescue
         
     | 
| 
      
 77 
     | 
    
         
            +
                      end
         
     | 
| 
      
 78 
     | 
    
         
            +
                    end
         
     | 
| 
      
 79 
     | 
    
         
            +
                  end
         
     | 
| 
      
 80 
     | 
    
         
            +
             
     | 
| 
      
 81 
     | 
    
         
            +
                  #.........................................................................................................
         
     | 
| 
      
 82 
     | 
    
         
            +
                  private :update_with_disco_info, :update_with_disco_items
         
     | 
| 
      
 83 
     | 
    
         
            +
             
     | 
| 
      
 84 
     | 
    
         
            +
                #### self
         
     | 
| 
      
 85 
     | 
    
         
            +
                end
         
     | 
| 
      
 86 
     | 
    
         
            +
             
     | 
| 
      
 87 
     | 
    
         
            +
              #### Service
         
     | 
| 
      
 88 
     | 
    
         
            +
              end
         
     | 
| 
      
 89 
     | 
    
         
            +
             
     | 
| 
      
 90 
     | 
    
         
            +
            #### AgentXmpp
         
     | 
| 
      
 91 
     | 
    
         
            +
            end
         
     |