blather 0.4.1 → 0.4.2
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/README.rdoc +16 -1
- data/examples/echo.rb +1 -1
- data/examples/ping.rb +11 -0
- data/examples/pong.rb +6 -0
- data/lib/blather/client.rb +5 -3
- data/lib/blather/client/client.rb +150 -51
- data/lib/blather/client/dsl.rb +24 -0
- data/lib/blather/client/dsl/pubsub.rb +16 -16
- data/lib/blather/errors.rb +14 -3
- data/lib/blather/jid.rb +14 -22
- data/lib/blather/stanza.rb +0 -16
- data/lib/blather/stanza/iq.rb +46 -5
- data/lib/blather/stanza/message.rb +141 -9
- data/lib/blather/stanza/presence.rb +49 -5
- data/lib/blather/stanza/presence/status.rb +68 -8
- data/lib/blather/stream/client.rb +6 -0
- data/lib/blather/stream/features.rb +1 -1
- data/spec/blather/client/client_spec.rb +131 -0
- data/spec/blather/client/dsl_spec.rb +20 -0
- data/spec/blather/stanza/message_spec.rb +17 -6
- data/spec/blather/stream/client_spec.rb +20 -0
- data/spec/blather/stream/component_spec.rb +1 -1
- metadata +4 -2
    
        data/README.rdoc
    CHANGED
    
    | @@ -101,6 +101,21 @@ The different types of guards are: | |
| 101 101 | 
             
              #   Equivalent to !stanza.find('/iq/ns:pubsub', :ns => 'pubsub:namespace').empty?
         | 
| 102 102 | 
             
              iq '/iq/ns:pubsub', :ns => 'pubsub:namespace'
         | 
| 103 103 |  | 
| 104 | 
            +
            === Filters
         | 
| 105 | 
            +
             | 
| 106 | 
            +
            Blather provides before and after filters that work much the way regular handlers work. Filters come in a before and after
         | 
| 107 | 
            +
            flavor. They're called in order of definition and can be guarded like handlers.
         | 
| 108 | 
            +
             | 
| 109 | 
            +
              before { |s| "I'm run before any handler" }
         | 
| 110 | 
            +
              before { |s| "I'm run next" }
         | 
| 111 | 
            +
             | 
| 112 | 
            +
              before(:message) { |s| "I'm only run in front of message stanzas" }
         | 
| 113 | 
            +
              before(nil, :id => 1) { |s| "I'll only be run when the stanza's ID == 1" }
         | 
| 114 | 
            +
             | 
| 115 | 
            +
              # ... handlers
         | 
| 116 | 
            +
             | 
| 117 | 
            +
              after { |s| "I'm run after everything" }
         | 
| 118 | 
            +
             | 
| 104 119 | 
             
            == On the Command Line:
         | 
| 105 120 |  | 
| 106 121 | 
             
            Default usage is:
         | 
| @@ -126,7 +141,7 @@ Command line options: | |
| 126 141 |  | 
| 127 142 | 
             
            Jeff Smick <sprsquish@gmail.com>
         | 
| 128 143 |  | 
| 129 | 
            -
             | 
| 144 | 
            +
            === Contributors
         | 
| 130 145 |  | 
| 131 146 | 
             
            Nolan Darilek <nolan@thewordnerd.info>
         | 
| 132 147 |  | 
    
        data/examples/echo.rb
    CHANGED
    
    
    
        data/examples/ping.rb
    ADDED
    
    
    
        data/examples/pong.rb
    ADDED
    
    
    
        data/lib/blather/client.rb
    CHANGED
    
    | @@ -7,8 +7,8 @@ options = {} | |
| 7 7 | 
             
            optparse = OptionParser.new do |opts|
         | 
| 8 8 | 
             
              opts.banner = "Run with #{$0} [options] user@server/resource password [host] [port]"
         | 
| 9 9 |  | 
| 10 | 
            -
              opts.on('-D', '--debug', 'Run in debug mode (you will see all XMPP communication)') do | 
| 11 | 
            -
                options[:debug] =  | 
| 10 | 
            +
              opts.on('-D', '--debug', 'Run in debug mode (you will see all XMPP communication)') do
         | 
| 11 | 
            +
                options[:debug] = true
         | 
| 12 12 | 
             
              end
         | 
| 13 13 |  | 
| 14 14 | 
             
              opts.on('-d', '--daemonize', 'Daemonize the process') do |daemonize|
         | 
| @@ -60,10 +60,12 @@ at_exit do | |
| 60 60 | 
             
                if options[:log]
         | 
| 61 61 | 
             
                  log = File.new(options[:log], 'a')
         | 
| 62 62 | 
             
                  log.sync = options[:debug]
         | 
| 63 | 
            -
                  Blather.logger.level = Logger::DEBUG if options[:debug]
         | 
| 64 63 | 
             
                  $stdout.reopen log
         | 
| 65 64 | 
             
                  $stderr.reopen $stdout
         | 
| 66 65 | 
             
                end
         | 
| 66 | 
            +
             | 
| 67 | 
            +
                Blather.logger.level = Logger::DEBUG if options[:debug]
         | 
| 68 | 
            +
             | 
| 67 69 | 
             
                trap(:INT) { EM.stop }
         | 
| 68 70 | 
             
                trap(:TERM) { EM.stop }
         | 
| 69 71 | 
             
                EM.run { client.run }
         | 
| @@ -2,29 +2,67 @@ require File.join(File.dirname(__FILE__), *%w[.. .. blather]) | |
| 2 2 |  | 
| 3 3 | 
             
            module Blather #:nodoc:
         | 
| 4 4 |  | 
| 5 | 
            -
               | 
| 5 | 
            +
              # = Blather Client
         | 
| 6 | 
            +
              #
         | 
| 7 | 
            +
              # Blather's Client class provides a set of helpers for working with common XMPP tasks such as setting up and starting
         | 
| 8 | 
            +
              # the connection, settings status, registering and dispatching filters and handlers and roster management.
         | 
| 9 | 
            +
              #
         | 
| 10 | 
            +
              # Client can be used separately from the DSL if you'd like to implement your own DSL
         | 
| 11 | 
            +
              # Here's the echo example using the client without the DSL:
         | 
| 12 | 
            +
              #
         | 
| 13 | 
            +
              #   require 'blather/client/client'
         | 
| 14 | 
            +
              #   client = Client.setup 'echo@jabber.local', 'echo'
         | 
| 15 | 
            +
              #
         | 
| 16 | 
            +
              #   client.register_handler(:ready) { puts "Connected ! send messages to #{client.jid.stripped}." }
         | 
| 17 | 
            +
              #
         | 
| 18 | 
            +
              #   client.register_handler :subscription, :request? do |s|
         | 
| 19 | 
            +
              #     client.write s.approve!
         | 
| 20 | 
            +
              #   end
         | 
| 21 | 
            +
              #
         | 
| 22 | 
            +
              #   client.register_handler :message, :chat?, :body => 'exit' do |m|
         | 
| 23 | 
            +
              #     client.write Blather::Stanza::Message.new(m.from, 'Exiting...')
         | 
| 24 | 
            +
              #     client.close
         | 
| 25 | 
            +
              #   end
         | 
| 26 | 
            +
              #
         | 
| 27 | 
            +
              #   client.register_handler :message, :chat?, :body do |m|
         | 
| 28 | 
            +
              #     client.write Blather::Stanza::Message.new(m.from, "You sent: #{m.body}")
         | 
| 29 | 
            +
              #   end
         | 
| 30 | 
            +
              #
         | 
| 31 | 
            +
              class Client
         | 
| 6 32 | 
             
                attr_reader :jid,
         | 
| 7 33 | 
             
                            :roster
         | 
| 8 34 |  | 
| 9 | 
            -
                 | 
| 35 | 
            +
                ##
         | 
| 36 | 
            +
                # Initialize and setup the client
         | 
| 37 | 
            +
                # * +jid+ - the JID to login with
         | 
| 38 | 
            +
                # * +password+ - password associated with the JID
         | 
| 39 | 
            +
                # * +host+ - hostname or IP to connect to. If nil the stream will look one up based on the domain in the JID
         | 
| 40 | 
            +
                # * +port+ - port to connect to
         | 
| 41 | 
            +
                def self.setup(jid, password, host = nil, port = nil)
         | 
| 42 | 
            +
                  self.new.setup(jid, password, host, port)
         | 
| 43 | 
            +
                end
         | 
| 44 | 
            +
             | 
| 45 | 
            +
                def initialize # :nodoc:
         | 
| 10 46 | 
             
                  @state = :initializing
         | 
| 11 47 |  | 
| 12 48 | 
             
                  @status = Stanza::Presence::Status.new
         | 
| 13 49 | 
             
                  @handlers = {}
         | 
| 14 50 | 
             
                  @tmp_handlers = {}
         | 
| 51 | 
            +
                  @filters = {:before => [], :after => []}
         | 
| 15 52 | 
             
                  @roster = Roster.new self
         | 
| 16 53 |  | 
| 17 54 | 
             
                  setup_initial_handlers
         | 
| 18 55 | 
             
                end
         | 
| 19 56 |  | 
| 20 | 
            -
                 | 
| 21 | 
            -
             | 
| 22 | 
            -
                end
         | 
| 23 | 
            -
             | 
| 57 | 
            +
                ##
         | 
| 58 | 
            +
                # Get the current status. Taken from the +state+ attribute of Status
         | 
| 24 59 | 
             
                def status
         | 
| 25 60 | 
             
                  @status.state
         | 
| 26 61 | 
             
                end
         | 
| 27 62 |  | 
| 63 | 
            +
                ##
         | 
| 64 | 
            +
                # Set the status. Status can be set with either a single value or an array containing
         | 
| 65 | 
            +
                # [state, message, to].
         | 
| 28 66 | 
             
                def status=(state)
         | 
| 29 67 | 
             
                  state, msg, to = state
         | 
| 30 68 |  | 
| @@ -35,77 +73,121 @@ module Blather #:nodoc: | |
| 35 73 | 
             
                  write status
         | 
| 36 74 | 
             
                end
         | 
| 37 75 |  | 
| 38 | 
            -
                 | 
| 39 | 
            -
             | 
| 40 | 
            -
                end
         | 
| 41 | 
            -
             | 
| 42 | 
            -
                def setup(jid, password, host = nil, port = nil)
         | 
| 43 | 
            -
                  @jid = JID.new(jid)
         | 
| 44 | 
            -
                  @setup = [@jid, password]
         | 
| 45 | 
            -
                  @setup << host if host
         | 
| 46 | 
            -
                  @setup << port if port
         | 
| 47 | 
            -
                  self
         | 
| 48 | 
            -
                end
         | 
| 49 | 
            -
             | 
| 76 | 
            +
                ##
         | 
| 77 | 
            +
                # Start the connection.
         | 
| 50 78 | 
             
                def run
         | 
| 51 79 | 
             
                  raise 'not setup!' unless setup?
         | 
| 52 80 | 
             
                  klass = @setup[0].node ? Blather::Stream::Client : Blather::Stream::Component
         | 
| 53 81 | 
             
                  @stream = klass.start self, *@setup
         | 
| 54 82 | 
             
                end
         | 
| 55 83 |  | 
| 84 | 
            +
                ##
         | 
| 85 | 
            +
                # Register a filter to be run before or after the handler chain is run.
         | 
| 86 | 
            +
                # * +type+ - the type of filter. Must be +:before+ or +:after+
         | 
| 87 | 
            +
                # * +guards+ - guards that should be checked before the filter is called
         | 
| 88 | 
            +
                def register_filter(type, handler = nil, *guards, &filter)
         | 
| 89 | 
            +
                  raise "Invalid filter: #{type}. Must be :before or :after" unless [:before, :after].include?(type)
         | 
| 90 | 
            +
                  @filters[type] << [guards, handler, filter]
         | 
| 91 | 
            +
                end
         | 
| 92 | 
            +
             | 
| 93 | 
            +
                ##
         | 
| 94 | 
            +
                # Register a temporary handler. Temporary handlers are based on the ID of the JID and live 
         | 
| 95 | 
            +
                # only until a stanza with said ID is received. 
         | 
| 96 | 
            +
                # * +id+ - the ID of the stanza that should be handled
         | 
| 56 97 | 
             
                def register_tmp_handler(id, &handler)
         | 
| 57 98 | 
             
                  @tmp_handlers[id] = handler
         | 
| 58 99 | 
             
                end
         | 
| 59 100 |  | 
| 101 | 
            +
                ##
         | 
| 102 | 
            +
                # Register a handler
         | 
| 103 | 
            +
                # * +type+ - the handler type. Should be registered in Stanza.handler_list. Blather will log a warning if it's not.
         | 
| 104 | 
            +
                # * +guards+ - the list of guards that must be verified before the handler will be called
         | 
| 60 105 | 
             
                def register_handler(type, *guards, &handler)
         | 
| 61 | 
            -
                   | 
| 106 | 
            +
                  check_handler type, guards
         | 
| 62 107 | 
             
                  @handlers[type] ||= []
         | 
| 63 108 | 
             
                  @handlers[type] << [guards, handler]
         | 
| 64 109 | 
             
                end
         | 
| 65 110 |  | 
| 111 | 
            +
                ##
         | 
| 112 | 
            +
                # Write data to the stream
         | 
| 66 113 | 
             
                def write(stanza)
         | 
| 67 114 | 
             
                  @stream.send(stanza) if @stream
         | 
| 68 115 | 
             
                end
         | 
| 69 116 |  | 
| 117 | 
            +
                ##
         | 
| 118 | 
            +
                # Helper that will create a temporary handler for the stanza being sent before writing it to the stream.
         | 
| 119 | 
            +
                #
         | 
| 120 | 
            +
                #   client.write_with_handler(stanza) { |s| "handle stanza here" }
         | 
| 121 | 
            +
                #
         | 
| 122 | 
            +
                # is equivalent to:
         | 
| 123 | 
            +
                #
         | 
| 124 | 
            +
                #   client.register_tmp_handler(stanza.id) { |s| "handle stanza here" }
         | 
| 125 | 
            +
                #   client.write stanza
         | 
| 70 126 | 
             
                def write_with_handler(stanza, &handler)
         | 
| 71 127 | 
             
                  register_tmp_handler stanza.id, &handler
         | 
| 72 128 | 
             
                  write stanza
         | 
| 73 129 | 
             
                end
         | 
| 74 130 |  | 
| 75 | 
            -
                 | 
| 76 | 
            -
             | 
| 77 | 
            -
                end
         | 
| 78 | 
            -
             | 
| 131 | 
            +
                ##
         | 
| 132 | 
            +
                # Close the connection
         | 
| 79 133 | 
             
                def close
         | 
| 80 134 | 
             
                  @stream.close_connection_after_writing
         | 
| 81 135 | 
             
                end
         | 
| 82 136 |  | 
| 83 | 
            -
                def  | 
| 137 | 
            +
                def post_init # :nodoc:
         | 
| 138 | 
            +
                  self.jid.node ? client_post_init : ready!
         | 
| 139 | 
            +
                end
         | 
| 140 | 
            +
             | 
| 141 | 
            +
                def unbind # :nodoc:
         | 
| 84 142 | 
             
                  EM.stop if EM.reactor_running?
         | 
| 85 143 | 
             
                end
         | 
| 86 144 |  | 
| 87 | 
            -
                def receive_data(stanza)
         | 
| 88 | 
            -
                   | 
| 89 | 
            -
                     | 
| 90 | 
            -
             | 
| 91 | 
            -
                     | 
| 92 | 
            -
                      break if call_handler_for(type, stanza)# && (stanza.is_a?(BlatherError) || stanza.type == :iq)
         | 
| 93 | 
            -
                    end
         | 
| 145 | 
            +
                def receive_data(stanza) # :nodoc:
         | 
| 146 | 
            +
                  catch(:halt) do
         | 
| 147 | 
            +
                    run_filters :before, stanza
         | 
| 148 | 
            +
                    handle_stanza stanza
         | 
| 149 | 
            +
                    run_filters :after, stanza
         | 
| 94 150 | 
             
                  end
         | 
| 95 151 | 
             
                end
         | 
| 96 152 |  | 
| 153 | 
            +
                def jid=(new_jid) # :nodoc :
         | 
| 154 | 
            +
                  @jid = JID.new new_jid
         | 
| 155 | 
            +
                end
         | 
| 156 | 
            +
             | 
| 157 | 
            +
                def setup? # :nodoc:
         | 
| 158 | 
            +
                  @setup.is_a? Array
         | 
| 159 | 
            +
                end
         | 
| 160 | 
            +
             | 
| 161 | 
            +
                def setup(jid, password, host = nil, port = nil) # :nodoc:
         | 
| 162 | 
            +
                  @jid = JID.new(jid)
         | 
| 163 | 
            +
                  @setup = [@jid, password]
         | 
| 164 | 
            +
                  @setup << host if host
         | 
| 165 | 
            +
                  @setup << port if port
         | 
| 166 | 
            +
                  self
         | 
| 167 | 
            +
                end
         | 
| 168 | 
            +
             | 
| 97 169 | 
             
              protected
         | 
| 98 | 
            -
                def  | 
| 170 | 
            +
                def check_handler(type, guards)
         | 
| 171 | 
            +
                  Blather.logger.warn "Handler for type \"#{type}\" will never be called as it's not a registered type" unless current_handlers.include?(type)
         | 
| 172 | 
            +
                  check_guards guards
         | 
| 173 | 
            +
                end
         | 
| 174 | 
            +
             | 
| 175 | 
            +
                def current_handlers
         | 
| 176 | 
            +
                  [:ready] + Stanza.handler_list + BlatherError.handler_list
         | 
| 177 | 
            +
                end
         | 
| 178 | 
            +
             | 
| 179 | 
            +
                def setup_initial_handlers # :nodoc:
         | 
| 99 180 | 
             
                  register_handler :error do |err|
         | 
| 100 181 | 
             
                    raise err
         | 
| 101 182 | 
             
                  end
         | 
| 102 183 |  | 
| 103 184 | 
             
                  register_handler :iq, :type => [:get, :set] do |iq|
         | 
| 104 | 
            -
                    write | 
| 185 | 
            +
                    write StanzaError.new(iq, 'service-unavailable', :cancel).to_node
         | 
| 105 186 | 
             
                  end
         | 
| 106 187 |  | 
| 107 188 | 
             
                  register_handler :status do |status|
         | 
| 108 189 | 
             
                    roster[status.from].status = status if roster[status.from]
         | 
| 190 | 
            +
                    nil
         | 
| 109 191 | 
             
                  end
         | 
| 110 192 |  | 
| 111 193 | 
             
                  register_handler :roster do |node|
         | 
| @@ -113,12 +195,12 @@ module Blather #:nodoc: | |
| 113 195 | 
             
                  end
         | 
| 114 196 | 
             
                end
         | 
| 115 197 |  | 
| 116 | 
            -
                def ready!
         | 
| 198 | 
            +
                def ready! # :nodoc:
         | 
| 117 199 | 
             
                  @state = :ready
         | 
| 118 200 | 
             
                  call_handler_for :ready, nil
         | 
| 119 201 | 
             
                end
         | 
| 120 202 |  | 
| 121 | 
            -
                def client_post_init
         | 
| 203 | 
            +
                def client_post_init # :nodoc:
         | 
| 122 204 | 
             
                  write_with_handler Stanza::Iq::Roster.new do |node|
         | 
| 123 205 | 
             
                    roster.process node
         | 
| 124 206 | 
             
                    write @status
         | 
| @@ -126,25 +208,43 @@ module Blather #:nodoc: | |
| 126 208 | 
             
                  end
         | 
| 127 209 | 
             
                end
         | 
| 128 210 |  | 
| 129 | 
            -
                def  | 
| 130 | 
            -
                   | 
| 131 | 
            -
                     | 
| 132 | 
            -
             | 
| 133 | 
            -
             | 
| 134 | 
            -
             | 
| 135 | 
            -
             | 
| 136 | 
            -
             | 
| 137 | 
            -
             | 
| 138 | 
            -
             | 
| 211 | 
            +
                def run_filters(type, stanza) # :nodoc:
         | 
| 212 | 
            +
                  @filters[type].each do |guards, handler, filter|
         | 
| 213 | 
            +
                    next if handler && !stanza.handler_heirarchy.include?(handler)
         | 
| 214 | 
            +
                    catch(:pass) { call_handler filter, guards, stanza }
         | 
| 215 | 
            +
                  end
         | 
| 216 | 
            +
                end
         | 
| 217 | 
            +
             | 
| 218 | 
            +
                def handle_stanza(stanza) # :nodoc:
         | 
| 219 | 
            +
                  if handler = @tmp_handlers.delete(stanza.id)
         | 
| 220 | 
            +
                    handler.call stanza
         | 
| 221 | 
            +
                  else
         | 
| 222 | 
            +
                    stanza.handler_heirarchy.each do |type|
         | 
| 223 | 
            +
                      break if call_handler_for(type, stanza)
         | 
| 139 224 | 
             
                    end
         | 
| 140 225 | 
             
                  end
         | 
| 141 226 | 
             
                end
         | 
| 142 227 |  | 
| 228 | 
            +
                def call_handler_for(type, stanza) # :nodoc:
         | 
| 229 | 
            +
                  return unless handler = @handlers[type]
         | 
| 230 | 
            +
                  handler.find do |guards, handler|
         | 
| 231 | 
            +
                    catch(:pass) { call_handler handler, guards, stanza }
         | 
| 232 | 
            +
                  end
         | 
| 233 | 
            +
                end
         | 
| 234 | 
            +
             | 
| 235 | 
            +
                def call_handler(handler, guards, stanza) # :nodoc:
         | 
| 236 | 
            +
                  if guards.first.respond_to?(:to_str) && !(result = stanza.find(*guards)).empty?
         | 
| 237 | 
            +
                    handler.call(stanza, result)
         | 
| 238 | 
            +
                  elsif !guarded?(guards, stanza)
         | 
| 239 | 
            +
                    handler.call(stanza)
         | 
| 240 | 
            +
                  end
         | 
| 241 | 
            +
                end
         | 
| 242 | 
            +
             | 
| 143 243 | 
             
                ##
         | 
| 144 244 | 
             
                # If any of the guards returns FALSE this returns true
         | 
| 145 245 | 
             
                # the logic is reversed to allow short circuiting
         | 
| 146 246 | 
             
                # (why would anyone want to loop over more values than necessary?)
         | 
| 147 | 
            -
                def guarded?(guards, stanza)
         | 
| 247 | 
            +
                def guarded?(guards, stanza) # :nodoc:
         | 
| 148 248 | 
             
                  guards.find do |guard|
         | 
| 149 249 | 
             
                    case guard
         | 
| 150 250 | 
             
                    when Symbol
         | 
| @@ -156,10 +256,9 @@ module Blather #:nodoc: | |
| 156 256 | 
             
                      # return FALSE unless any inequality is found
         | 
| 157 257 | 
             
                      guard.find do |method, test|
         | 
| 158 258 | 
             
                        value = stanza.__send__(method)
         | 
| 159 | 
            -
                         | 
| 160 | 
            -
             | 
| 161 | 
            -
             | 
| 162 | 
            -
                        when Array
         | 
| 259 | 
            +
                        if test.class.respond_to?(:last_match)
         | 
| 260 | 
            +
                          !(test =~ value)
         | 
| 261 | 
            +
                        elsif test.is_a?(Array)
         | 
| 163 262 | 
             
                          !test.include? value
         | 
| 164 263 | 
             
                        else
         | 
| 165 264 | 
             
                          test != value
         | 
| @@ -171,7 +270,7 @@ module Blather #:nodoc: | |
| 171 270 | 
             
                  end
         | 
| 172 271 | 
             
                end
         | 
| 173 272 |  | 
| 174 | 
            -
                def check_guards(guards)
         | 
| 273 | 
            +
                def check_guards(guards) # :nodoc:
         | 
| 175 274 | 
             
                  guards.each do |guard|
         | 
| 176 275 | 
             
                    case guard
         | 
| 177 276 | 
             
                    when Array
         | 
    
        data/lib/blather/client/dsl.rb
    CHANGED
    
    | @@ -38,6 +38,18 @@ module Blather | |
| 38 38 | 
             
                  client.close
         | 
| 39 39 | 
             
                end
         | 
| 40 40 |  | 
| 41 | 
            +
                ##
         | 
| 42 | 
            +
                # Setup a before filter
         | 
| 43 | 
            +
                def before(handler = nil, *guards, &block)
         | 
| 44 | 
            +
                  client.register_filter :before, handler, *guards, &block
         | 
| 45 | 
            +
                end
         | 
| 46 | 
            +
             | 
| 47 | 
            +
                ##
         | 
| 48 | 
            +
                # Setup an after filter
         | 
| 49 | 
            +
                def after(handler = nil, *guards, &block)
         | 
| 50 | 
            +
                  client.register_filter :after, handler, *guards, &block
         | 
| 51 | 
            +
                end
         | 
| 52 | 
            +
             | 
| 41 53 | 
             
                ##
         | 
| 42 54 | 
             
                # Set handler for a stanza type
         | 
| 43 55 | 
             
                def handle(stanza_type, *guards, &block)
         | 
| @@ -82,6 +94,18 @@ module Blather | |
| 82 94 | 
             
                  client.jid
         | 
| 83 95 | 
             
                end
         | 
| 84 96 |  | 
| 97 | 
            +
                ##
         | 
| 98 | 
            +
                # Halt the handler chain
         | 
| 99 | 
            +
                def halt
         | 
| 100 | 
            +
                  throw :halt
         | 
| 101 | 
            +
                end
         | 
| 102 | 
            +
             | 
| 103 | 
            +
                ##
         | 
| 104 | 
            +
                # Pass responsibility to the next handler
         | 
| 105 | 
            +
                def pass
         | 
| 106 | 
            +
                  throw :pass
         | 
| 107 | 
            +
                end
         | 
| 108 | 
            +
             | 
| 85 109 | 
             
                ##
         | 
| 86 110 | 
             
                # Request items or info from an entity
         | 
| 87 111 | 
             
                #   discover (items|info), [jid], [node] do |response|
         | 
| @@ -27,7 +27,7 @@ module DSL | |
| 27 27 | 
             
                ##
         | 
| 28 28 | 
             
                # Discover Nodes
         | 
| 29 29 | 
             
                # Yields a list of DiscoItem::Item objects
         | 
| 30 | 
            -
                # | 
| 30 | 
            +
                # * +path+ is the node's path. Default is '/'
         | 
| 31 31 | 
             
                def nodes(path = nil, host = nil, &callback)
         | 
| 32 32 | 
             
                  path ||= '/'
         | 
| 33 33 | 
             
                  stanza = Stanza::DiscoItems.new(:get, path)
         | 
| @@ -38,7 +38,7 @@ module DSL | |
| 38 38 | 
             
                ##
         | 
| 39 39 | 
             
                # Discover node information
         | 
| 40 40 | 
             
                # Yields a DiscoInfo node
         | 
| 41 | 
            -
                # | 
| 41 | 
            +
                # * +path+ is the node's path
         | 
| 42 42 | 
             
                def node(path, host = nil, &callback)
         | 
| 43 43 | 
             
                  stanza = Stanza::DiscoInfo.new(:get, path)
         | 
| 44 44 | 
             
                  stanza.to = send_to(host)
         | 
| @@ -47,9 +47,9 @@ module DSL | |
| 47 47 |  | 
| 48 48 | 
             
                ##
         | 
| 49 49 | 
             
                # Retrieve items for a node
         | 
| 50 | 
            -
                # | 
| 51 | 
            -
                # | 
| 52 | 
            -
                # | 
| 50 | 
            +
                # * +path+ is the node's path
         | 
| 51 | 
            +
                # * +list+ can be an array of items to retrieve
         | 
| 52 | 
            +
                # * +max+ can be the maximum number of items to return
         | 
| 53 53 | 
             
                def items(path, list = [], max = nil, host = nil, &callback)
         | 
| 54 54 | 
             
                  request Stanza::PubSub::Items.request(send_to(host), path, list, max), :items, callback
         | 
| 55 55 | 
             
                end
         | 
| @@ -57,8 +57,8 @@ module DSL | |
| 57 57 | 
             
                ##
         | 
| 58 58 | 
             
                # Subscribe to a node
         | 
| 59 59 | 
             
                # Yields the resulting Subscription object
         | 
| 60 | 
            -
                # | 
| 61 | 
            -
                # | 
| 60 | 
            +
                # * +node+ is the node to subscribe to
         | 
| 61 | 
            +
                # * +jid+ is the jid that should be used. Defaults to the stripped current JID
         | 
| 62 62 | 
             
                def subscribe(node, jid = nil, host = nil)
         | 
| 63 63 | 
             
                  jid ||= DSL.client.jid.stripped
         | 
| 64 64 | 
             
                  request(Stanza::PubSub::Subscribe.new(:set, send_to(host), node, jid)) { |n| yield n if block_given? }
         | 
| @@ -67,8 +67,8 @@ module DSL | |
| 67 67 | 
             
                ##
         | 
| 68 68 | 
             
                # Unsubscribe from a node
         | 
| 69 69 | 
             
                # Yields the resulting Unsubscribe object
         | 
| 70 | 
            -
                # | 
| 71 | 
            -
                # | 
| 70 | 
            +
                # * +node+ is the node to subscribe to
         | 
| 71 | 
            +
                # * +jid+ is the jid that should be used. Defaults to the stripped current JID
         | 
| 72 72 | 
             
                def unsubscribe(node, jid = nil, host = nil)
         | 
| 73 73 | 
             
                  jid ||= DSL.client.jid.stripped
         | 
| 74 74 | 
             
                  request(Stanza::PubSub::Unsubscribe.new(:set, send_to(host), node, jid)) { |n| yield n if block_given? }
         | 
| @@ -77,8 +77,8 @@ module DSL | |
| 77 77 | 
             
                ##
         | 
| 78 78 | 
             
                # Publish an item to a node
         | 
| 79 79 | 
             
                # Yields the resulting Publish node
         | 
| 80 | 
            -
                # | 
| 81 | 
            -
                # | 
| 80 | 
            +
                # * +node+ is the node to publish to
         | 
| 81 | 
            +
                # * +payload+ is the payload to send (see Blather::Stanza::PubSub::Publish for details)
         | 
| 82 82 | 
             
                def publish(node, payload, host = nil)
         | 
| 83 83 | 
             
                  request(Stanza::PubSub::Publish.new(send_to(host), node, :set, payload)) { |n| yield n if block_given? }
         | 
| 84 84 | 
             
                end
         | 
| @@ -86,8 +86,8 @@ module DSL | |
| 86 86 | 
             
                ##
         | 
| 87 87 | 
             
                # Delete items from a node
         | 
| 88 88 | 
             
                # Yields the resulting node
         | 
| 89 | 
            -
                # | 
| 90 | 
            -
                # | 
| 89 | 
            +
                # * +node+ is the node to retract items from
         | 
| 90 | 
            +
                # * +ids+ is a list of ids to retract. This can also be a single id
         | 
| 91 91 | 
             
                def retract(node, ids = [], host = nil)
         | 
| 92 92 | 
             
                  request(Stanza::PubSub::Retract.new(send_to(host), node, :set, ids)) { |n| yield n if block_given? }
         | 
| 93 93 | 
             
                end
         | 
| @@ -96,7 +96,7 @@ module DSL | |
| 96 96 | 
             
                # Create a node
         | 
| 97 97 | 
             
                # Yields the resulting node
         | 
| 98 98 | 
             
                # This does not (yet) handle configuration
         | 
| 99 | 
            -
                # | 
| 99 | 
            +
                # * +node+ is the node to create
         | 
| 100 100 | 
             
                def create(node, host = nil)
         | 
| 101 101 | 
             
                  request(Stanza::PubSub::Create.new(:set, send_to(host), node)) { |n| yield n if block_given? }
         | 
| 102 102 | 
             
                end
         | 
| @@ -104,7 +104,7 @@ module DSL | |
| 104 104 | 
             
                ##
         | 
| 105 105 | 
             
                # Purge all node items
         | 
| 106 106 | 
             
                # Yields the resulting node
         | 
| 107 | 
            -
                # | 
| 107 | 
            +
                # * +node+ is the node to purge
         | 
| 108 108 | 
             
                def purge(node, host = nil)
         | 
| 109 109 | 
             
                  request(Stanza::PubSubOwner::Purge.new(:set, send_to(host), node)) { |n| yield n if block_given? }
         | 
| 110 110 | 
             
                end
         | 
| @@ -112,7 +112,7 @@ module DSL | |
| 112 112 | 
             
                ##
         | 
| 113 113 | 
             
                # Delete a node
         | 
| 114 114 | 
             
                # Yields the resulting node
         | 
| 115 | 
            -
                # | 
| 115 | 
            +
                # * +node+ is the node to delete
         | 
| 116 116 | 
             
                def delete(node, host = nil)
         | 
| 117 117 | 
             
                  request(Stanza::PubSubOwner::Delete.new(:set, send_to(host), node)) { |n| yield n if block_given? }
         | 
| 118 118 | 
             
                end
         |