class GxG::Networking::XmppAgent
XMPP Client
Public Class Methods
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
# 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
# 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
# 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
# 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
# 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
# File lib/gxg/net_clients.rb, line 3296 def <<(stanza) if @client @client.write stanza end self end
# 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
### 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
### 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
# 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
Review : debug only method
# File lib/gxg/net_clients.rb, line 3582 def client() @client end
# 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
# 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
### 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
### 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
# File lib/gxg/net_clients.rb, line 3994 def download_directory() @file_transfers_thread_safety.synchronize { @download_directory } end
# 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 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
# 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
# File lib/gxg/net_clients.rb, line 3367 def get_status() if @client @client.status else :unavailable end end
# 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 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
### 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
# 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
### 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
# File lib/gxg/net_clients.rb, line 3433 def jid_domain() jid = self.jid if jid jid.domain() else nil end end
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
# File lib/gxg/net_clients.rb, line 3441 def jid_resource() jid = self.jid if jid jid.resource() else nil end end
### 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
# 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
# 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
# File lib/gxg/net_clients.rb, line 3767 def logout if @client @client.clear_handlers :disconnected @client.close @client = nil end # true end
### 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
# 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 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
# File lib/gxg/net_clients.rb, line 3303 def publish_and_subscribe @pubsub end
# 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
# 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
# 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
# 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
### 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 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
# 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 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 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
### 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
Support Methods
# File lib/gxg/net_clients.rb, line 3289 def write(stanza) if @client @client.write stanza end true end
### 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
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